shape ops work in progress
milestone: about 1.6M tests pass
git-svn-id: http://skia.googlecode.com/svn/trunk@5035 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/experimental/Intersection/EdgeWalkerPolygon4x4_Test.cpp b/experimental/Intersection/EdgeWalkerPolygon4x4_Test.cpp
index c9d6bdd..e795cd0 100755
--- a/experimental/Intersection/EdgeWalkerPolygon4x4_Test.cpp
+++ b/experimental/Intersection/EdgeWalkerPolygon4x4_Test.cpp
@@ -1,169 +1,176 @@
#include "EdgeWalker_Test.h"
#include "Intersection_Tests.h"
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include <assert.h>
-#include <pthread.h>
static void* testSimplify4x4QuadralateralsMain(void* data)
{
- char pathStr[1024];
- bzero(pathStr, sizeof(pathStr));
SkASSERT(data);
State4& state = *(State4*) data;
- int ax = state.a & 0x03;
- int ay = state.a >> 2;
- int bx = state.b & 0x03;
- int by = state.b >> 2;
- int cx = state.c & 0x03;
- int cy = state.c >> 2;
- int dx = state.d & 0x03;
- int dy = state.d >> 2;
- for (int e = 0 ; e < 16; ++e) {
- int ex = e & 0x03;
- int ey = e >> 2;
- for (int f = e ; f < 16; ++f) {
- int fx = f & 0x03;
- int fy = f >> 2;
- for (int g = f ; g < 16; ++g) {
- int gx = g & 0x03;
- int gy = g >> 2;
- for (int h = g ; h < 16; ++h) {
- int hx = h & 0x03;
- int hy = h >> 2;
+ char pathStr[1024];
+ bzero(pathStr, sizeof(pathStr));
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ int dx = state.d & 0x03;
+ int dy = state.d >> 2;
+ for (int e = 0 ; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = e ; f < 16; ++f) {
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ for (int g = f ; g < 16; ++g) {
+ int gx = g & 0x03;
+ int gy = g >> 2;
+ for (int h = g ; h < 16; ++h) {
+ int hx = h & 0x03;
+ int hy = h >> 2;
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(ax, ay);
+ path.lineTo(bx, by);
+ path.lineTo(cx, cy);
+ path.lineTo(dx, dy);
+ path.close();
+ path.moveTo(ex, ey);
+ path.lineTo(fx, fy);
+ path.lineTo(gx, gy);
+ path.lineTo(hx, hy);
+ path.close();
+ if (1) { // gdb: set print elements 400
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", gx, gy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", hx, hy);
+ str += sprintf(str, " path.close();\n");
+ }
+ outputProgress(state, pathStr);
+ testSimplifyx(path, out, state, pathStr);
+ state.testsRun++;
+ #if 0 // FIXME: enable once we have support for even/odd
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplifyx(path, true, out, state, pathStr);
+ state.testsRun++;
+ #endif
+ }
+ }
+ }
+ }
+ } while (runNextTestSet(state));
+ return NULL;
+}
+
+void Simplify4x4QuadralateralsThreaded_Test()
+{
+ SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4; // FIXME: 3?
+ gDebugMaxWindValue = 4;
+#endif
+ const char testStr[] = "testQuadralateral";
+ initializeTests(testStr, sizeof(testStr));
+ int testsRun = 0;
+ for (int a = 0; a < 16; ++a) {
+ for (int b = a ; b < 16; ++b) {
+ for (int c = b ; c < 16; ++c) {
+ for (int d = c; d < 16; ++d) {
+ testsRun += dispatchTest4(testSimplify4x4QuadralateralsMain,
+ a, b, c, d);
+ }
+ if (!gRunTestsInOneThread) SkDebugf(".");
+ }
+ if (!gRunTestsInOneThread) SkDebugf("%d", b);
+ }
+ if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
+ }
+ testsRun += waitForCompletion();
+ SkDebugf("%s total tests run=%d\n", __FUNCTION__, testsRun);
+}
+
+
+static void* testSimplify4x4NondegeneratesMain(void* data) {
+ SkASSERT(data);
+ State4& state = *(State4*) data;
+ char pathStr[1024];
+ bzero(pathStr, sizeof(pathStr));
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ for (int d = 0; d < 15; ++d) {
+ int dx = d & 0x03;
+ int dy = d >> 2;
+ for (int e = d + 1; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = d + 1; f < 16; ++f) {
+ if (e == f) {
+ continue;
+ }
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ if ((ex - dx) * (fy - dy) == (ey - dy) * (fx - dx)) {
+ continue;
+ }
SkPath path, out;
path.setFillType(SkPath::kWinding_FillType);
path.moveTo(ax, ay);
path.lineTo(bx, by);
path.lineTo(cx, cy);
- path.lineTo(dx, dy);
path.close();
- path.moveTo(ex, ey);
+ path.moveTo(dx, dy);
+ path.lineTo(ex, ey);
path.lineTo(fx, fy);
- path.lineTo(gx, gy);
- path.lineTo(hx, hy);
path.close();
- if (1) { // gdb: set print elements 400
+ if (1) {
char* str = pathStr;
str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
- str += sprintf(str, " path.lineTo(%d, %d);\n", dx, dy);
str += sprintf(str, " path.close();\n");
- str += sprintf(str, " path.moveTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.moveTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", ex, ey);
str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
- str += sprintf(str, " path.lineTo(%d, %d);\n", gx, gy);
- str += sprintf(str, " path.lineTo(%d, %d);\n", hx, hy);
- str += sprintf(str, " path.close();");
+ str += sprintf(str, " path.close();\n");
}
- if (!testSimplify(path, true, out, state.bitmap, state.canvas)) {
- SkDebugf("*/\n{ SkPath::kWinding_FillType, %d, %d, %d, %d,"
- " %d, %d, %d, %d },\n/*\n", state.a, state.b, state.c, state.d,
- e, f, g, h);
- }
+ outputProgress(state, pathStr);
+ testSimplifyx(path, out, state, pathStr);
+ state.testsRun++;
+ #if 0 // FIXME: enable once we have support for even/odd
path.setFillType(SkPath::kEvenOdd_FillType);
- if (!testSimplify(path, true, out, state.bitmap, state.canvas)) {
- SkDebugf("*/\n{ SkPath::kEvenOdd_FillType, %d, %d, %d, %d,"
- " %d, %d, %d, %d },\n/*\n", state.a, state.b, state.c, state.d,
- e, f, g, h);
- }
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplifyx(path, true, out, state, pathStr);
+ state.testsRun++;
+ #endif
}
}
}
- }
- return NULL;
-}
-
-const int maxThreads = gRunTestsInOneThread ? 1 : 24;
-
-void Simplify4x4QuadralateralsThreaded_Test()
-{
- State4 threadState[maxThreads];
- int threadIndex = 0;
- for (int a = 0; a < 16; ++a) {
- for (int b = a ; b < 16; ++b) {
- for (int c = b ; c < 16; ++c) {
- for (int d = c; d < 16; ++d) {
- State4* statePtr = &threadState[threadIndex];
- statePtr->a = a;
- statePtr->b = b;
- statePtr->c = c;
- statePtr->d = d;
- if (maxThreads > 1) {
- createThread(statePtr, testSimplify4x4QuadralateralsMain);
- if (++threadIndex >= maxThreads) {
- waitForCompletion(threadState, threadIndex);
- }
- } else {
- testSimplify4x4QuadralateralsMain(statePtr);
- }
- }
- }
- }
- }
- waitForCompletion(threadState, threadIndex);
-}
-
-
-static void* testSimplify4x4NondegeneratesMain(void* data) {
- char pathStr[1024];
- bzero(pathStr, sizeof(pathStr));
- SkASSERT(data);
- State4& state = *(State4*) data;
- int ax = state.a & 0x03;
- int ay = state.a >> 2;
- int bx = state.b & 0x03;
- int by = state.b >> 2;
- int cx = state.c & 0x03;
- int cy = state.c >> 2;
- for (int d = 0; d < 15; ++d) {
- int dx = d & 0x03;
- int dy = d >> 2;
- for (int e = d + 1; e < 16; ++e) {
- int ex = e & 0x03;
- int ey = e >> 2;
- for (int f = d + 1; f < 16; ++f) {
- if (e == f) {
- continue;
- }
- int fx = f & 0x03;
- int fy = f >> 2;
- if ((ex - dx) * (fy - dy) == (ey - dy) * (fx - dx)) {
- continue;
- }
- SkPath path, out;
- path.setFillType(SkPath::kWinding_FillType);
- path.moveTo(ax, ay);
- path.lineTo(bx, by);
- path.lineTo(cx, cy);
- path.close();
- path.moveTo(dx, dy);
- path.lineTo(ex, ey);
- path.lineTo(fx, fy);
- path.close();
- if (1) {
- char* str = pathStr;
- str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
- str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
- str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
- str += sprintf(str, " path.close();\n");
- str += sprintf(str, " path.moveTo(%d, %d);\n", dx, dy);
- str += sprintf(str, " path.lineTo(%d, %d);\n", ex, ey);
- str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
- str += sprintf(str, " path.close();");
- }
- testSimplify(path, true, out, state.bitmap, state.canvas);
- path.setFillType(SkPath::kEvenOdd_FillType);
- testSimplify(path, true, out, state.bitmap, state.canvas);
- }
- }
- }
+ } while (runNextTestSet(state));
return NULL;
}
void SimplifyNondegenerate4x4TrianglesThreaded_Test() {
- State4 threadState[maxThreads];
- int threadIndex = 0;
+ SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 2;
+ gDebugMaxWindValue = 2;
+#endif
+ const char testStr[] = "testNondegenerate";
+ initializeTests(testStr, sizeof(testStr));
+ int testsRun = 0;
for (int a = 0; a < 15; ++a) {
int ax = a & 0x03;
int ay = a >> 2;
@@ -179,81 +186,88 @@
if ((bx - ax) * (cy - ay) == (by - ay) * (cx - ax)) {
continue;
}
- State4* statePtr = &threadState[threadIndex];
- statePtr->a = a;
- statePtr->b = b;
- statePtr->c = c;
- if (maxThreads > 1) {
- createThread(statePtr, testSimplify4x4NondegeneratesMain);
- if (++threadIndex >= maxThreads) {
- waitForCompletion(threadState, threadIndex);
- }
- } else {
- testSimplify4x4NondegeneratesMain(statePtr);
- }
+ testsRun += dispatchTest4(testSimplify4x4NondegeneratesMain,
+ a, b, c, 0);
}
+ if (!gRunTestsInOneThread) SkDebugf(".");
}
+ if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
}
- waitForCompletion(threadState, threadIndex);
+ testsRun += waitForCompletion();
+ SkDebugf("%s total tests run=%d\n", __FUNCTION__, testsRun);
}
static void* testSimplify4x4DegeneratesMain(void* data) {
- char pathStr[1024];
- bzero(pathStr, sizeof(pathStr));
SkASSERT(data);
State4& state = *(State4*) data;
- int ax = state.a & 0x03;
- int ay = state.a >> 2;
- int bx = state.b & 0x03;
- int by = state.b >> 2;
- int cx = state.c & 0x03;
- int cy = state.c >> 2;
- for (int d = 0; d < 16; ++d) {
- int dx = d & 0x03;
- int dy = d >> 2;
- for (int e = d ; e < 16; ++e) {
- int ex = e & 0x03;
- int ey = e >> 2;
- for (int f = d ; f < 16; ++f) {
- int fx = f & 0x03;
- int fy = f >> 2;
- if (state.abcIsATriangle && (ex - dx) * (fy - dy)
- != (ey - dy) * (fx - dx)) {
- continue;
+ char pathStr[1024];
+ bzero(pathStr, sizeof(pathStr));
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ for (int d = 0; d < 16; ++d) {
+ int dx = d & 0x03;
+ int dy = d >> 2;
+ for (int e = d ; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = d ; f < 16; ++f) {
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ if (state.d && (ex - dx) * (fy - dy)
+ != (ey - dy) * (fx - dx)) {
+ continue;
+ }
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(ax, ay);
+ path.lineTo(bx, by);
+ path.lineTo(cx, cy);
+ path.close();
+ path.moveTo(dx, dy);
+ path.lineTo(ex, ey);
+ path.lineTo(fx, fy);
+ path.close();
+ if (1) {
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.close();\n");
+ }
+ outputProgress(state, pathStr);
+ testSimplifyx(path, out, state, pathStr);
+ state.testsRun++;
+ #if 0 // FIXME: enable once we have support for even/odd
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplifyx(path, true, out, state, pathStr);
+ state.testsRun++;
+ #endif
}
- SkPath path, out;
- path.setFillType(SkPath::kWinding_FillType);
- path.moveTo(ax, ay);
- path.lineTo(bx, by);
- path.lineTo(cx, cy);
- path.close();
- path.moveTo(dx, dy);
- path.lineTo(ex, ey);
- path.lineTo(fx, fy);
- path.close();
- if (1) {
- char* str = pathStr;
- str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
- str += sprintf(str, " path.lineTo(%d, %d);\n", bx, by);
- str += sprintf(str, " path.lineTo(%d, %d);\n", cx, cy);
- str += sprintf(str, " path.close();\n");
- str += sprintf(str, " path.moveTo(%d, %d);\n", dx, dy);
- str += sprintf(str, " path.lineTo(%d, %d);\n", ex, ey);
- str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
- str += sprintf(str, " path.close();");
- }
- testSimplify(path, true, out, state.bitmap, state.canvas);
- path.setFillType(SkPath::kEvenOdd_FillType);
- testSimplify(path, true, out, state.bitmap, state.canvas);
}
}
- }
+ } while (runNextTestSet(state));
return NULL;
}
void SimplifyDegenerate4x4TrianglesThreaded_Test() {
- State4 threadState[maxThreads];
- int threadIndex = 0;
+ SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 2;
+ gDebugMaxWindValue = 2;
+#endif
+ const char testStr[] = "testDegenerate";
+ initializeTests(testStr, sizeof(testStr));
+ int testsRun = 0;
for (int a = 0; a < 16; ++a) {
int ax = a & 0x03;
int ay = a >> 2;
@@ -263,23 +277,15 @@
for (int c = a ; c < 16; ++c) {
int cx = c & 0x03;
int cy = c >> 2;
- State4* statePtr = &threadState[threadIndex];
- statePtr->abcIsATriangle = (bx - ax) * (cy - ay)
- != (by - ay) * (cx - ax);
- statePtr->a = a;
- statePtr->b = b;
- statePtr->c = c;
- if (maxThreads > 1) {
- createThread(statePtr, testSimplify4x4DegeneratesMain);
- if (++threadIndex >= maxThreads) {
- waitForCompletion(threadState, threadIndex);
- }
- } else {
- testSimplify4x4DegeneratesMain(statePtr);
- }
+ bool abcIsATriangle = (bx - ax) * (cy - ay) != (by - ay) * (cx - ax);
+ testsRun += dispatchTest4(testSimplify4x4DegeneratesMain,
+ a, b, c, abcIsATriangle);
}
+ if (!gRunTestsInOneThread) SkDebugf(".");
}
+ if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
}
- waitForCompletion(threadState, threadIndex);
+ testsRun += waitForCompletion();
+ SkDebugf("%s total tests run=%d\n", __FUNCTION__, testsRun);
}
diff --git a/experimental/Intersection/EdgeWalkerQuadratic4x4_Test.cpp b/experimental/Intersection/EdgeWalkerQuadratic4x4_Test.cpp
index 75fd9a4..f714249 100644
--- a/experimental/Intersection/EdgeWalkerQuadratic4x4_Test.cpp
+++ b/experimental/Intersection/EdgeWalkerQuadratic4x4_Test.cpp
@@ -7,95 +7,92 @@
static void* testSimplify4x4QuadraticsMain(void* data)
{
- char pathStr[1024];
- bzero(pathStr, sizeof(pathStr));
SkASSERT(data);
State4& state = *(State4*) data;
- int ax = state.a & 0x03;
- int ay = state.a >> 2;
- int bx = state.b & 0x03;
- int by = state.b >> 2;
- int cx = state.c & 0x03;
- int cy = state.c >> 2;
- int dx = state.d & 0x03;
- int dy = state.d >> 2;
- for (int e = 0 ; e < 16; ++e) {
- int ex = e & 0x03;
- int ey = e >> 2;
- for (int f = e ; f < 16; ++f) {
- int fx = f & 0x03;
- int fy = f >> 2;
- for (int g = f ; g < 16; ++g) {
- int gx = g & 0x03;
- int gy = g >> 2;
- for (int h = g ; h < 16; ++h) {
- int hx = h & 0x03;
- int hy = h >> 2;
- SkPath path, out;
- path.setFillType(SkPath::kWinding_FillType);
- path.moveTo(ax, ay);
- path.quadTo(bx, by, cx, cy);
- path.lineTo(dx, dy);
- path.close();
- path.moveTo(ex, ey);
- path.lineTo(fx, fy);
- path.quadTo(gx, gy, hx, hy);
- path.close();
- if (1) { // gdb: set print elements 400
- char* str = pathStr;
- str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
- str += sprintf(str, " path.quadTo(%d, %d, %d, %d);\n", bx, by, cx, cy);
- str += sprintf(str, " path.lineTo(%d, %d);\n", dx, dy);
- str += sprintf(str, " path.close();\n");
- str += sprintf(str, " path.moveTo(%d, %d);\n", ex, ey);
- str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
- str += sprintf(str, " path.quadTo(%d, %d, %d, %d);\n", gx, gy, hx, hy);
- str += sprintf(str, " path.close();");
- }
- if (!testSimplify(path, true, out, state.bitmap, state.canvas)) {
- SkDebugf("*/\n{ SkPath::kWinding_FillType, %d, %d, %d, %d,"
- " %d, %d, %d, %d },\n/*\n", state.a, state.b, state.c, state.d,
- e, f, g, h);
- }
- path.setFillType(SkPath::kEvenOdd_FillType);
- if (!testSimplify(path, true, out, state.bitmap, state.canvas)) {
- SkDebugf("*/\n{ SkPath::kEvenOdd_FillType, %d, %d, %d, %d,"
- " %d, %d, %d, %d },\n/*\n", state.a, state.b, state.c, state.d,
- e, f, g, h);
+ char pathStr[1024];
+ bzero(pathStr, sizeof(pathStr));
+ do {
+ int ax = state.a & 0x03;
+ int ay = state.a >> 2;
+ int bx = state.b & 0x03;
+ int by = state.b >> 2;
+ int cx = state.c & 0x03;
+ int cy = state.c >> 2;
+ int dx = state.d & 0x03;
+ int dy = state.d >> 2;
+ for (int e = 0 ; e < 16; ++e) {
+ int ex = e & 0x03;
+ int ey = e >> 2;
+ for (int f = e ; f < 16; ++f) {
+ int fx = f & 0x03;
+ int fy = f >> 2;
+ for (int g = f ; g < 16; ++g) {
+ int gx = g & 0x03;
+ int gy = g >> 2;
+ for (int h = g ; h < 16; ++h) {
+ int hx = h & 0x03;
+ int hy = h >> 2;
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(ax, ay);
+ path.quadTo(bx, by, cx, cy);
+ path.lineTo(dx, dy);
+ path.close();
+ path.moveTo(ex, ey);
+ path.lineTo(fx, fy);
+ path.quadTo(gx, gy, hx, hy);
+ path.close();
+ if (1) { // gdb: set print elements 400
+ char* str = pathStr;
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ax, ay);
+ str += sprintf(str, " path.quadTo(%d, %d, %d, %d);\n", bx, by, cx, cy);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", dx, dy);
+ str += sprintf(str, " path.close();\n");
+ str += sprintf(str, " path.moveTo(%d, %d);\n", ex, ey);
+ str += sprintf(str, " path.lineTo(%d, %d);\n", fx, fy);
+ str += sprintf(str, " path.quadTo(%d, %d, %d, %d);\n", gx, gy, hx, hy);
+ str += sprintf(str, " path.close();\n");
+ }
+ outputProgress(state, pathStr);
+ testSimplifyx(path, out, state, pathStr);
+ state.testsRun++;
+ #if 0 // FIXME: enable once we have support for even/odd
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplifyx(path, true, out, state, pathStr);
+ state.testsRun++;
+ #endif
}
}
}
}
- }
+ } while (runNextTestSet(state));
return NULL;
}
-const int maxThreads = gRunTestsInOneThread ? 1 : 24;
-
void Simplify4x4QuadraticsThreaded_Test()
{
- State4 threadState[maxThreads];
- int threadIndex = 0;
+ SkDebugf("%s\n", __FUNCTION__);
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4; // FIXME: 3?
+ gDebugMaxWindValue = 4;
+#endif
+ const char testStr[] = "testQuadratic";
+ initializeTests(testStr, sizeof(testStr));
+ int testsRun = 0;
for (int a = 0; a < 16; ++a) {
for (int b = a ; b < 16; ++b) {
for (int c = b ; c < 16; ++c) {
for (int d = c; d < 16; ++d) {
- State4* statePtr = &threadState[threadIndex];
- statePtr->a = a;
- statePtr->b = b;
- statePtr->c = c;
- statePtr->d = d;
- if (maxThreads > 1) {
- createThread(statePtr, testSimplify4x4QuadraticsMain);
- if (++threadIndex >= maxThreads) {
- waitForCompletion(threadState, threadIndex);
- }
- } else {
- testSimplify4x4QuadraticsMain(statePtr);
- }
+ testsRun += dispatchTest4(testSimplify4x4QuadraticsMain,
+ a, b, c, d);
}
+ if (!gRunTestsInOneThread) SkDebugf(".");
}
+ if (!gRunTestsInOneThread) SkDebugf("%d", b);
}
+ if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
}
- waitForCompletion(threadState, threadIndex);
+ testsRun += waitForCompletion();
+ SkDebugf("%s total tests run=%d\n", __FUNCTION__, testsRun);
}
diff --git a/experimental/Intersection/EdgeWalker_Test.h b/experimental/Intersection/EdgeWalker_Test.h
index 492ba70..229a94d 100644
--- a/experimental/Intersection/EdgeWalker_Test.h
+++ b/experimental/Intersection/EdgeWalker_Test.h
@@ -5,6 +5,7 @@
#include <pthread.h>
class SkCanvas;
+struct State4;
//extern int comparePaths(const SkPath& one, const SkPath& two);
extern int comparePaths(const SkPath& one, const SkPath& two, SkBitmap& bitmap,
@@ -16,7 +17,7 @@
extern bool testSimplify(const SkPath& path, bool fill, SkPath& out,
SkBitmap& bitmap, SkCanvas* canvas = 0);
extern bool testSimplifyx(const SkPath& path, SkPath& out,
- SkBitmap& bitmap, SkCanvas* canvas = 0);
+ State4& state, const char* pathStr);
extern bool testSimplifyx(const SkPath& path);
struct State4 {
@@ -25,7 +26,6 @@
static pthread_cond_t checkQueue;
pthread_cond_t initialized;
static State4* queue;
- State4* next;
pthread_t threadID;
int index;
bool done;
@@ -33,14 +33,18 @@
int a;
int b;
int c;
- int d;
+ int d; // sometimes 1 if abc_is_a_triangle
int testsRun;
char filename[256];
SkCanvas* canvas;
SkBitmap bitmap;
- bool abcIsATriangle;
};
void createThread(State4* statePtr, void* (*test)(void* ));
-void waitForCompletion(State4 threadState[], int& threadIndex);
+int dispatchTest4(void* (*testFun)(void* ), int a, int b, int c, int d);
+void initializeTests(const char* testName, size_t testNameSize);
+void outputProgress(const State4& state, const char* pathStr);
+void outputToStream(const State4& state, const char* pathStr, SkWStream& outFile);
+bool runNextTestSet(State4& state);
+int waitForCompletion();
diff --git a/experimental/Intersection/EdgeWalker_TestUtility.cpp b/experimental/Intersection/EdgeWalker_TestUtility.cpp
index 7e65e8f..7baa17b 100644
--- a/experimental/Intersection/EdgeWalker_TestUtility.cpp
+++ b/experimental/Intersection/EdgeWalker_TestUtility.cpp
@@ -3,17 +3,38 @@
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkPaint.h"
+#include "SkStream.h"
+
#include <algorithm>
+#include <assert.h>
+#include <errno.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
#undef SkASSERT
#define SkASSERT(cond) while (!(cond)) { sk_throw(); }
+static const char marker[] =
+ "</div>\n"
+ "\n"
+ "<script type=\"text/javascript\">\n"
+ "\n"
+ "var testDivs = [\n";
+#if 0
+static const char filename[] = "../../experimental/Intersection/debugXX.txt";
+#else
+static const char filename[] = "/flash/debug/XX.txt";
+#endif
+
static bool gShowPath = false;
static bool gComparePaths = true;
//static bool gDrawLastAsciiPaths = true;
static bool gDrawAllAsciiPaths = false;
static bool gShowAsciiPaths = false;
-static bool gComparePathsAssert = true;
+static bool gComparePathsAssert = false;
+static bool gPathStrAssert = true;
void showPath(const SkPath& path, const char* str) {
SkDebugf("%s\n", !str ? "original:" : str);
@@ -196,16 +217,17 @@
SkScalar yScale = std::max(24.0f / larger.height(), 1.0f);
errors = scaledDrawTheSame(one, two, xScale, yScale, false, bitmap, canvas);
if (errors > 5) {
+ SkDebugf("\n");
scaledDrawTheSame(one, two, xScale, yScale, true, bitmap, canvas);
}
}
- if (errors > max) {
- SkDebugf("\n%s errors=%d\n", __FUNCTION__, errors);
+ const int MAX_ERRORS = 20;
+ if (errors > max && errors <= MAX_ERRORS) {
+ SkDebugf("%s errors=%d\n", __FUNCTION__, errors);
max = errors;
}
- const int MAX_ERRORS = 20;
- if (errors > MAX_ERRORS) SkDebugf("\n%s errors=%d\n", __FUNCTION__, errors);
if (errors > MAX_ERRORS && gComparePathsAssert) {
+ SkDebugf("%s errors=%d\n", __FUNCTION__, errors);
showPath(one);
showPath(two, "simplified:");
SkASSERT(0);
@@ -256,8 +278,8 @@
return comparePaths(path, out, bitmap, canvas) == 0;
}
-bool testSimplifyx(const SkPath& path, SkPath& out, SkBitmap& bitmap,
- SkCanvas* canvas) {
+bool testSimplifyx(const SkPath& path, SkPath& out, State4& state,
+ const char* pathStr) {
if (gShowPath) {
showPath(path);
}
@@ -265,7 +287,16 @@
if (!gComparePaths) {
return true;
}
- return comparePaths(path, out, bitmap, canvas) == 0;
+ int result = comparePaths(path, out, state.bitmap, state.canvas);
+ if (result && gPathStrAssert) {
+ char temp[8192];
+ bzero(temp, sizeof(temp));
+ SkMemoryWStream stream(temp, sizeof(temp));
+ outputToStream(state, pathStr, stream);
+ SkDebugf(temp);
+ SkASSERT(0);
+ }
+ return result == 0;
}
bool testSimplifyx(const SkPath& path) {
@@ -281,22 +312,232 @@
return comparePaths(path, out, bitmap, 0) == 0;
}
+const int maxThreadsAllocated = 64;
+static int maxThreads = 1;
+static int threadIndex;
+State4 threadState[maxThreadsAllocated];
+static int testNumber;
+static const char* testName;
+static bool debugThreads = false;
+
+State4* State4::queue = NULL;
+pthread_mutex_t State4::addQueue = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t State4::checkQueue = PTHREAD_COND_INITIALIZER;
+
State4::State4() {
bitmap.setConfig(SkBitmap::kARGB_8888_Config, 150 * 2, 100);
bitmap.allocPixels();
canvas = new SkCanvas(bitmap);
}
-void createThread(State4* statePtr, void* (*test)(void* )) {
- int threadError = pthread_create(&statePtr->threadID, NULL, test,
+void createThread(State4* statePtr, void* (*testFun)(void* )) {
+ int threadError = pthread_create(&statePtr->threadID, NULL, testFun,
(void*) statePtr);
SkASSERT(!threadError);
}
-void waitForCompletion(State4 threadState[], int& threadIndex) {
- for (int index = 0; index < threadIndex; ++index) {
- pthread_join(threadState[index].threadID, NULL);
+int dispatchTest4(void* (*testFun)(void* ), int a, int b, int c, int d) {
+ int testsRun = 0;
+
+ if (!gRunTestsInOneThread) {
+ State4* statePtr;
+ pthread_mutex_lock(&State4::addQueue);
+ if (threadIndex < maxThreads) {
+ statePtr = &threadState[threadIndex];
+ statePtr->testsRun = 0;
+ statePtr->a = a;
+ statePtr->b = b;
+ statePtr->c = c;
+ statePtr->d = d;
+ statePtr->done = false;
+ statePtr->index = threadIndex;
+ statePtr->last = false;
+ if (debugThreads) SkDebugf("%s %d create done=%d last=%d\n", __FUNCTION__,
+ statePtr->index, statePtr->done, statePtr->last);
+ pthread_cond_init(&statePtr->initialized, NULL);
+ ++threadIndex;
+ createThread(statePtr, testFun);
+ } else {
+ while (!State4::queue) {
+ if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__);
+ pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
+ }
+ statePtr = State4::queue;
+ testsRun += statePtr->testsRun;
+ statePtr->testsRun = 0;
+ statePtr->a = a;
+ statePtr->b = b;
+ statePtr->c = c;
+ statePtr->d = d;
+ statePtr->done = false;
+ State4::queue = NULL;
+ for (int index = 0; index < maxThreads; ++index) {
+ if (threadState[index].done) {
+ State4::queue = &threadState[index];
+ }
+ }
+ if (debugThreads) SkDebugf("%s %d init done=%d last=%d queued=%d\n", __FUNCTION__,
+ statePtr->index, statePtr->done, statePtr->last,
+ State4::queue ? State4::queue->index : -1);
+ pthread_cond_signal(&statePtr->initialized);
+ }
+ pthread_mutex_unlock(&State4::addQueue);
+ } else {
+ State4 state;
+ state.a = a;
+ state.b = b;
+ state.c = c;
+ state.d = d;
+ (*testFun)(&state);
+ testsRun++;
}
- SkDebugf(".");
+ return testsRun;
+}
+
+void initializeTests(const char* test, size_t testNameSize) {
+ testName = test;
+ if (!gRunTestsInOneThread) {
+ int threads = -1;
+ size_t size = sizeof(threads);
+ sysctlbyname("hw.logicalcpu_max", &threads, &size, NULL, 0);
+ if (threads > 0) {
+ maxThreads = threads;
+ } else {
+ maxThreads = 8;
+ }
+ }
+ if (!gRunTestsInOneThread) {
+ SkFILEStream inFile("../../experimental/Intersection/op.htm");
+ if (inFile.isValid()) {
+ SkTDArray<char> inData;
+ inData.setCount(inFile.getLength());
+ size_t inLen = inData.count();
+ inFile.read(inData.begin(), inLen);
+ inFile.setPath(NULL);
+ char* insert = strstr(inData.begin(), marker);
+ if (insert) {
+ insert += sizeof(marker) - 1;
+ const char* numLoc = insert + 4 /* indent spaces */ + testNameSize - 1;
+ testNumber = atoi(numLoc) + 1;
+ }
+ }
+ }
+ for (int index = 0; index < maxThreads; ++index) {
+ State4* statePtr = &threadState[index];
+ strcpy(statePtr->filename, filename);
+ SkASSERT(statePtr->filename[sizeof(filename) - 7] == 'X');
+ SkASSERT(statePtr->filename[sizeof(filename) - 6] == 'X');
+ statePtr->filename[sizeof(filename) - 7] = '0' + index / 10;
+ statePtr->filename[sizeof(filename) - 6] = '0' + index % 10;
+ }
threadIndex = 0;
}
+
+void outputProgress(const State4& state, const char* pathStr) {
+ if (gRunTestsInOneThread) {
+ SkDebugf("%s\n", pathStr);
+ } else {
+ SkFILEWStream outFile(state.filename);
+ if (!outFile.isValid()) {
+ SkASSERT(0);
+ return;
+ }
+ outputToStream(state, pathStr, outFile);
+ }
+}
+
+void outputToStream(const State4& state, const char* pathStr, SkWStream& outFile) {
+ outFile.writeText("<div id=\"");
+ outFile.writeText(testName);
+ outFile.writeDecAsText(testNumber);
+ outFile.writeText("\">\n");
+ outFile.writeText(pathStr);
+ outFile.writeText("</div>\n\n");
+
+ outFile.writeText(marker);
+ outFile.writeText(" ");
+ outFile.writeText(testName);
+ outFile.writeDecAsText(testNumber);
+ outFile.writeText(",\n\n\n");
+
+ outFile.writeText("static void ");
+ outFile.writeText(testName);
+ outFile.writeDecAsText(testNumber);
+ outFile.writeText("() {\n SkPath path;\n");
+ outFile.writeText(pathStr);
+ outFile.writeText(" testSimplifyx(path);\n}\n\n");
+ outFile.writeText("static void (*firstTest)() = ");
+ outFile.writeText(testName);
+ outFile.writeDecAsText(testNumber);
+ outFile.writeText(";\n\n");
+
+ outFile.writeText("static struct {\n");
+ outFile.writeText(" void (*fun)();\n");
+ outFile.writeText(" const char* str;\n");
+ outFile.writeText("} tests[] = {\n");
+ outFile.writeText(" TEST(");
+ outFile.writeText(testName);
+ outFile.writeDecAsText(testNumber);
+ outFile.writeText("),\n");
+ outFile.flush();
+}
+
+bool runNextTestSet(State4& state) {
+ if (gRunTestsInOneThread) {
+ return false;
+ }
+ pthread_mutex_lock(&State4::addQueue);
+ state.done = true;
+ State4::queue = &state;
+ if (debugThreads) SkDebugf("%s %d checkQueue done=%d last=%d\n", __FUNCTION__, state.index,
+ state.done, state.last);
+ pthread_cond_signal(&State4::checkQueue);
+ while (state.done && !state.last) {
+ if (debugThreads) SkDebugf("%s %d done=%d last=%d\n", __FUNCTION__, state.index, state.done, state.last);
+ pthread_cond_wait(&state.initialized, &State4::addQueue);
+ }
+ pthread_mutex_unlock(&State4::addQueue);
+ return !state.last;
+}
+
+int waitForCompletion() {
+ int testsRun = 0;
+ if (!gRunTestsInOneThread) {
+ pthread_mutex_lock(&State4::addQueue);
+ int runningThreads = maxThreads;
+ int index;
+ while (runningThreads > 0) {
+ while (!State4::queue) {
+ if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__);
+ pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
+ }
+ while (State4::queue) {
+ --runningThreads;
+ SkDebugf("•");
+ State4::queue->last = true;
+ State4* next;
+ for (index = 0; index < maxThreads; ++index) {
+ State4& test = threadState[index];
+ if (test.done && !test.last) {
+ next = &test;
+ }
+ }
+ if (debugThreads) SkDebugf("%s %d next=%d deQueue\n", __FUNCTION__,
+ State4::queue->index, next ? next->index : -1);
+ pthread_cond_signal(&State4::queue->initialized);
+ State4::queue = next;
+ }
+ }
+ pthread_mutex_unlock(&State4::addQueue);
+ for (index = 0; index < maxThreads; ++index) {
+ pthread_join(threadState[index].threadID, NULL);
+ testsRun += threadState[index].testsRun;
+ }
+ SkDebugf("\n");
+ }
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = SK_MaxS32;
+ gDebugMaxWindValue = SK_MaxS32;
+#endif
+ return testsRun;
+}
diff --git a/experimental/Intersection/Intersection_Tests.cpp b/experimental/Intersection/Intersection_Tests.cpp
index 017f1d1..414b911 100644
--- a/experimental/Intersection/Intersection_Tests.cpp
+++ b/experimental/Intersection/Intersection_Tests.cpp
@@ -7,7 +7,11 @@
void Intersection_Tests() {
SimplifyNew_Test();
+ Simplify4x4QuadralateralsThreaded_Test();
+ Simplify4x4QuadraticsThreaded_Test();
Simplify4x4RectsThreaded_Test();
+ SimplifyNondegenerate4x4TrianglesThreaded_Test();
+ SimplifyDegenerate4x4TrianglesThreaded_Test();
SimplifyFindNext_Test();
SimplifyFindTop_Test();
SimplifyAngle_Test();
@@ -35,15 +39,6 @@
SimplifyQuadralateralPaths_Test();
ActiveEdge_Test();
-#if TEST_QUADS_FIRST
- Simplify4x4QuadraticsThreaded_Test();
-#endif
- SimplifyDegenerate4x4TrianglesThreaded_Test();
- SimplifyNondegenerate4x4TrianglesThreaded_Test();
- Simplify4x4QuadralateralsThreaded_Test();
-#if !TEST_QUADS_FIRST
- Simplify4x4QuadraticsThreaded_Test();
-#endif
QuadraticCoincidence_Test();
QuadraticIntersection_Test();
diff --git a/experimental/Intersection/Simplify.cpp b/experimental/Intersection/Simplify.cpp
index 0b8eccf..9ffa33c 100644
--- a/experimental/Intersection/Simplify.cpp
+++ b/experimental/Intersection/Simplify.cpp
@@ -27,7 +27,7 @@
#define DEBUG_UNUSED 0 // set to expose unused functions
-#if 01 // set to 1 for multiple thread -- no debugging
+#if 0 // set to 1 for multiple thread -- no debugging
const bool gRunTestsInOneThread = false;
@@ -677,7 +677,6 @@
int fWindSum; // accumulated from contours surrounding this one
int fWindValue; // 0 == canceled; 1 == normal; >1 == coincident
bool fDone; // if set, this span to next higher T has been processed
- bool fOutside; // if set, sum is outside, sum + sign * value computes inside
};
class Segment {
@@ -981,7 +980,6 @@
span->fPt.fX = SK_ScalarNaN;
span->fWindSum = SK_MinS32;
span->fWindValue = 1;
- span->fOutside = false;
if ((span->fDone = newT == 1)) {
++fDoneSpans;
}
@@ -1008,6 +1006,7 @@
int oIndex = other.fTs.count();
while (other.fTs[--oIndex].fT - oEndT > -FLT_EPSILON)
;
+ double tRatio = (oEndT - oStartT) / (endT - startT);
Span* test = &fTs[index];
Span* oTest = &other.fTs[oIndex];
SkTDArray<double> outsideTs;
@@ -1027,7 +1026,12 @@
span = &fTs[++index];
} while (span->fT - testT < FLT_EPSILON);
Span* oSpan = oTest;
- do {
+ double otherTMatchStart = oEndT - (span->fT - startT) * tRatio;
+ double otherTMatchEnd = oEndT - (test->fT - startT) * tRatio;
+ SkDEBUGCODE(int originalWindValue = oSpan->fWindValue);
+ while (oSpan->fT > otherTMatchStart - FLT_EPSILON
+ && otherTMatchEnd - FLT_EPSILON > oSpan->fT) {
+ SkASSERT(originalWindValue == oSpan->fWindValue);
if (decrement) {
other.decrementSpan(oSpan);
} else if (track && oSpan->fT < 1 && testT < 1) {
@@ -1037,11 +1041,11 @@
break;
}
oSpan = &other.fTs[--oIndex];
- } while (oTestT - oSpan->fT < FLT_EPSILON);
+ }
test = span;
oTest = oSpan;
} while (test->fT < endT - FLT_EPSILON);
- SkASSERT(!oIndex || oTest->fT <= oStartT - FLT_EPSILON);
+ SkASSERT(!oIndex || oTest->fT < oStartT + FLT_EPSILON);
// FIXME: determine if canceled edges need outside ts added
if (!done() && outsideTs.count()) {
double tStart = outsideTs[0];
@@ -1075,6 +1079,7 @@
while (oStartT - other.fTs[oIndex].fT >= FLT_EPSILON) {
++oIndex;
}
+ double tRatio = (oEndT - oStartT) / (endT - startT);
Span* test = &fTs[index];
Span* oTest = &other.fTs[oIndex];
SkTDArray<double> outsideTs;
@@ -1092,7 +1097,7 @@
do {
if (transfer) {
if (decrementOther) {
- SkASSERT(abs(end->fWindValue) <= gDebugMaxWindValue);
+ SkASSERT(abs(end->fWindValue) < gDebugMaxWindValue);
++(end->fWindValue);
} else if (decrementSpan(end)) {
TrackOutside(outsideTs, end->fT, oStartT);
@@ -1105,11 +1110,16 @@
}
end = &fTs[++index];
} while (end->fT - test->fT < FLT_EPSILON);
+ // because of the order in which coincidences are resolved, this and other
+ // may not have the same intermediate points. Compute the corresponding
+ // intermediate T values (using this as the master, other as the follower)
+ // and walk other conditionally -- hoping that it catches up in the end
+ double otherTMatch = (test->fT - startT) * tRatio + oStartT;
Span* oEnd = oTest;
- do {
+ while (oEnd->fT < oEndT - FLT_EPSILON && oEnd->fT - otherTMatch < FLT_EPSILON) {
if (transfer) {
if (!decrementOther) {
- SkASSERT(abs(oEnd->fWindValue) <= gDebugMaxWindValue);
+ SkASSERT(abs(oEnd->fWindValue) < gDebugMaxWindValue);
++(oEnd->fWindValue);
} else if (other.decrementSpan(oEnd)) {
TrackOutside(oOutsideTs, oEnd->fT, startT);
@@ -1121,7 +1131,7 @@
}
}
oEnd = &other.fTs[++oIndex];
- } while (oEnd->fT - oTest->fT < FLT_EPSILON);
+ }
test = end;
oTest = oEnd;
} while (test->fT < endT - FLT_EPSILON);
@@ -1261,8 +1271,8 @@
int spanWinding = base->spanSign(angle);
bool inner = useInnerWinding(winding + spanWinding, winding);
#if DEBUG_WINDING
- SkDebugf("%s --- spanWinding=%d winding=%d sign=%d inner=%d outside=%d result=%d\n", __FUNCTION__,
- spanWinding, winding, angle->sign(), inner, base->spanOutside(angle->start(), angle->end()),
+ SkDebugf("%s --- spanWinding=%d winding=%d sign=%d inner=%d result=%d\n", __FUNCTION__,
+ spanWinding, winding, angle->sign(), inner,
inner ? winding + spanWinding : winding);
#endif
if (inner) {
@@ -1283,11 +1293,10 @@
int maxWinding = winding;
winding -= segment->spanSign(angle);
if (segment->windSum(angle) == SK_MinS32) {
- bool inside = useInnerWinding(maxWinding, winding);
- if (inside) {
+ if (useInnerWinding(maxWinding, winding)) {
maxWinding = winding;
}
- segment->markAndChaseWinding(angle, maxWinding, !inside);
+ segment->markAndChaseWinding(angle, maxWinding);
}
} while (++nextIndex != lastIndex);
return windSum(SkMin32(startIndex, endIndex));
@@ -1323,7 +1332,7 @@
SkPoint pt;
double foundT = intersections.fT[0][0];
(*SegmentXYAtT[fVerb])(fPts, foundT, &pt);
- if (bestY < pt.fY) {
+ if (bestY < pt.fY && pt.fY < basePt.fY) {
bestY = pt.fY;
bestT = foundT < 1 ? start : end;
hitT = fTs[start].fT + (fTs[end].fT - fTs[start].fT) * foundT;
@@ -1422,8 +1431,7 @@
SkDebugf("%s winding=%d spanWinding=%d outerWinding=%d innerWinding=%d\n",
__FUNCTION__, winding, spanWinding, outerWinding, innerWinding);
#endif
- bool inside = useInnerWinding(outerWinding, innerWinding);
- if (inside) {
+ if (useInnerWinding(outerWinding, innerWinding)) {
outerWinding = innerWinding;
}
SkASSERT(startIndex != endIndex);
@@ -1441,7 +1449,7 @@
#if DEBUG_WINDING
SkDebugf("%s simple\n", __FUNCTION__);
#endif
- markDone(SkMin32(startIndex, endIndex), outerWinding, !inside);
+ markDone(SkMin32(startIndex, endIndex), outerWinding);
other = endSpan->fOther;
nextStart = endSpan->fOtherIndex;
double startT = other->fTs[nextStart].fT;
@@ -1502,10 +1510,10 @@
}
if (!sumWinding) {
if (!active) {
- markDone(SkMin32(startIndex, endIndex), outerWinding, !inside);
+ markDone(SkMin32(startIndex, endIndex), outerWinding);
// FIXME: seems like a bug that this isn't calling userInnerWinding
nextSegment->markWinding(SkMin32(nextAngle->start(),
- nextAngle->end()), maxWinding, true);
+ nextAngle->end()), maxWinding);
#if DEBUG_WINDING
SkDebugf("%s inactive\n", __FUNCTION__);
#endif
@@ -1561,15 +1569,14 @@
// as done, record the winding value, and mark connected unambiguous
// segments as well.
if (nextSegment->windSum(nextAngle) == SK_MinS32) {
- bool inside = useInnerWinding(maxWinding, sumWinding);
- if (inside) {
+ if (useInnerWinding(maxWinding, sumWinding)) {
maxWinding = sumWinding;
}
Span* last;
if (foundAngle) {
- last = nextSegment->markAndChaseWinding(nextAngle, maxWinding, !inside);
+ last = nextSegment->markAndChaseWinding(nextAngle, maxWinding);
} else {
- last = nextSegment->markAndChaseDone(nextAngle, maxWinding, !inside);
+ last = nextSegment->markAndChaseDone(nextAngle, maxWinding);
}
if (last) {
*chase.append() = last;
@@ -1577,7 +1584,7 @@
}
} while (++nextIndex != lastIndex);
SkASSERT(sorted[firstIndex]->segment() == this);
- markDone(SkMin32(startIndex, endIndex), outerWinding, !inside);
+ markDone(SkMin32(startIndex, endIndex), outerWinding);
if (!foundAngle) {
return NULL;
}
@@ -1806,7 +1813,7 @@
}
// OPTIMIZATION: uses tail recursion. Unwise?
- Span* innerChaseDone(int index, int step, int winding, bool outside) {
+ Span* innerChaseDone(int index, int step, int winding) {
int end = nextSpan(index, step);
SkASSERT(end >= 0);
if (multipleSpans(end)) {
@@ -1816,12 +1823,12 @@
Segment* other = endSpan.fOther;
index = endSpan.fOtherIndex;
int otherEnd = other->nextSpan(index, step);
- Span* last = other->innerChaseDone(index, step, winding, outside);
- other->markDone(SkMin32(index, otherEnd), winding, outside);
+ Span* last = other->innerChaseDone(index, step, winding);
+ other->markDone(SkMin32(index, otherEnd), winding);
return last;
}
- Span* innerChaseWinding(int index, int step, int winding, bool outside) {
+ Span* innerChaseWinding(int index, int step, int winding) {
int end = nextSpan(index, step);
SkASSERT(end >= 0);
if (multipleSpans(end)) {
@@ -1836,8 +1843,8 @@
SkASSERT(other->fTs[min].fWindSum == winding);
return NULL;
}
- Span* last = other->innerChaseWinding(index, step, winding, outside);
- other->markWinding(min, winding, outside);
+ Span* last = other->innerChaseWinding(index, step, winding);
+ other->markWinding(min, winding);
return last;
}
@@ -1914,22 +1921,22 @@
// this span is excluded by the winding rule -- chase the ends
// as long as they are unambiguous to mark connections as done
// and give them the same winding value
- Span* markAndChaseDone(const Angle* angle, int winding, bool outside) {
+ Span* markAndChaseDone(const Angle* angle, int winding) {
int index = angle->start();
int endIndex = angle->end();
int step = SkSign32(endIndex - index);
- Span* last = innerChaseDone(index, step, winding, outside);
- markDone(SkMin32(index, endIndex), winding, outside);
+ Span* last = innerChaseDone(index, step, winding);
+ markDone(SkMin32(index, endIndex), winding);
return last;
}
- Span* markAndChaseWinding(const Angle* angle, int winding, bool outside) {
+ Span* markAndChaseWinding(const Angle* angle, int winding) {
int index = angle->start();
int endIndex = angle->end();
int min = SkMin32(index, endIndex);
int step = SkSign32(endIndex - index);
- Span* last = innerChaseWinding(index, step, winding, outside);
- markWinding(min, winding, outside);
+ Span* last = innerChaseWinding(index, step, winding);
+ markWinding(min, winding);
return last;
}
@@ -1938,7 +1945,7 @@
// wastes time, it shouldn't do any more than spin through the T spans.
// OPTIMIZATION: abort on first done found (assuming that this code is
// always called to mark segments done).
- void markDone(int index, int winding, bool outside) {
+ void markDone(int index, int winding) {
// SkASSERT(!done());
double referenceT = fTs[index].fT;
int lesser = index;
@@ -1954,7 +1961,6 @@
SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
SkASSERT(abs(winding) <= gDebugMaxWindSum);
span.fWindSum = winding;
- span.fOutside = outside;
fDoneSpans++;
}
do {
@@ -1970,12 +1976,11 @@
SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
SkASSERT(abs(winding) <= gDebugMaxWindSum);
span.fWindSum = winding;
- span.fOutside = outside;
fDoneSpans++;
} while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
}
- void markWinding(int index, int winding, bool outside) {
+ void markWinding(int index, int winding) {
// SkASSERT(!done());
double referenceT = fTs[index].fT;
int lesser = index;
@@ -1991,7 +1996,6 @@
SkASSERT(span.fWindSum == SK_MinS32 || span.fWindSum == winding);
SkASSERT(abs(winding) <= gDebugMaxWindSum);
span.fWindSum = winding;
- span.fOutside = outside;
}
do {
Span& span = fTs[index];
@@ -2006,7 +2010,6 @@
#endif
SkASSERT(abs(winding) <= gDebugMaxWindSum);
span.fWindSum = winding;
- span.fOutside = outside;
} while (++index < fTs.count() && fTs[index].fT - referenceT < FLT_EPSILON);
}
@@ -2083,10 +2086,6 @@
return fTs[tIndex];
}
- const bool spanOutside(int startIndex, int endIndex) const {
- return fTs[SkMin32(startIndex, endIndex)].fOutside;
- }
-
int spanSign(int startIndex, int endIndex) const {
int result = startIndex < endIndex ? -fTs[startIndex].fWindValue :
fTs[endIndex].fWindValue;
@@ -2711,9 +2710,9 @@
complete();
if (!fCurrentContour) {
fCurrentContour = fContours.push_back_n(1);
- finalCurveEnd = pointsPtr++;
*fExtra.append() = -1; // start new contour
}
+ finalCurveEnd = pointsPtr++;
continue;
case SkPath::kLine_Verb:
// skip degenerate points
@@ -3240,6 +3239,13 @@
end = test->nextSpan(tIndex, -1);
}
test->addTwoAngles(end, tIndex, angles);
+ SkASSERT(angles.count() > 0);
+ if (angles[0].segment()->yAtT(angles[0].start()) >= basePt.fY) {
+#if DEBUG_SORT
+ SkDebugf("%s *** early return\n", __FUNCTION__);
+#endif
+ return 0;
+ }
test->buildAngles(tIndex, angles);
SkTDArray<Angle*> sorted;
// OPTIMIZATION: call a sort that, if base point is the leftmost,
@@ -3259,7 +3265,7 @@
int right = -1;
bool baseMatches = test->yAtT(tIndex) == basePt.fY;
for (int index = 0; index < count; ++index) {
- const Angle* angle = sorted[index];
+ angle = sorted[index];
if (baseMatches && angle->isHorizontal()) {
continue;
}
@@ -3268,6 +3274,17 @@
left = index;
} else if (indexDx > 0) {
right = index;
+ int previous = index - 1;
+ if (previous < 0) {
+ previous = count - 1;
+ }
+ const Angle* prev = sorted[previous];
+ if (prev->dy() >= 0 && prev->dx() > 0 && angle->dy() < 0) {
+#if DEBUG_SORT
+ SkDebugf("%s use prev\n", __FUNCTION__);
+#endif
+ right = previous;
+ }
break;
} else {
mid = index;
@@ -3427,11 +3444,10 @@
// FIXME: this be wrong. assign startWinding if edge is in
// same direction. If the direction is opposite, winding to
// assign is flipped sign or +/- 1?
- bool inside = useInnerWinding(maxWinding, winding);
- if (inside) {
+ if (useInnerWinding(maxWinding, winding)) {
maxWinding = winding;
}
- segment->markWinding(lesser, maxWinding, !inside);
+ segment->markWinding(lesser, maxWinding);
#endif
break;
}
@@ -3495,9 +3511,9 @@
contourWinding -= spanWinding;
}
#if DEBUG_WINDING
- SkDebugf("%s --- sumWinding=%d spanWinding=%d sign=%d inner=%d outside=%d result=%d\n", __FUNCTION__,
+ SkDebugf("%s --- sumWinding=%d spanWinding=%d sign=%d inner=%d result=%d\n", __FUNCTION__,
sumWinding, spanWinding, SkSign32(index - endIndex),
- inner, current->spanOutside(index, endIndex), contourWinding);
+ inner, contourWinding);
#endif
}
#if DEBUG_WINDING
@@ -3561,11 +3577,10 @@
bool inner = useInnerWinding(winding - spanWinding, winding);
#if DEBUG_WINDING
SkDebugf("%s --- id=%d t=%1.9g spanWinding=%d winding=%d sign=%d"
- " inner=%d outside=%d result=%d\n",
+ " inner=%d result=%d\n",
__FUNCTION__, current->debugID(), current->t(lesser),
spanWinding, winding, SkSign32(index - endIndex),
useInnerWinding(winding - spanWinding, winding),
- current->spanOutside(index, endIndex),
inner ? winding - spanWinding : winding);
#endif
if (inner) {
diff --git a/experimental/Intersection/SimplifyNew_Test.cpp b/experimental/Intersection/SimplifyNew_Test.cpp
index 74e78f5..3d21908 100644
--- a/experimental/Intersection/SimplifyNew_Test.cpp
+++ b/experimental/Intersection/SimplifyNew_Test.cpp
@@ -12,7 +12,7 @@
#define TEST(name) { name, #name }
static void testLine1() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(2,0);
path.lineTo(1,1);
path.lineTo(0,0);
@@ -49,49 +49,49 @@
}
static void testLine2() {
- SkPath path, simple;
+ SkPath path;
addInnerCWTriangle(path);
addOuterCWTriangle(path);
testSimplifyx(path);
}
static void testLine3() {
- SkPath path, simple;
+ SkPath path;
addInnerCCWTriangle(path);
addOuterCWTriangle(path);
testSimplifyx(path);
}
static void testLine3a() {
- SkPath path, simple;
+ SkPath path;
addInnerCWTriangle(path);
addOuterCCWTriangle(path);
testSimplifyx(path);
}
static void testLine3b() {
- SkPath path, simple;
+ SkPath path;
addInnerCCWTriangle(path);
addOuterCCWTriangle(path);
testSimplifyx(path);
}
static void testLine4() {
- SkPath path, simple;
+ SkPath path;
addOuterCCWTriangle(path);
addOuterCWTriangle(path);
testSimplifyx(path);
}
static void testLine5() {
- SkPath path, simple;
+ SkPath path;
addOuterCWTriangle(path);
addOuterCWTriangle(path);
testSimplifyx(path);
}
static void testLine6() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(0,0);
path.lineTo(4,0);
path.lineTo(2,2);
@@ -104,7 +104,7 @@
}
static void testLine7() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(0,0);
path.lineTo(4,0);
path.lineTo(2,2);
@@ -117,7 +117,7 @@
}
static void testLine7a() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(0,0);
path.lineTo(4,0);
path.lineTo(2,2);
@@ -126,7 +126,7 @@
}
static void testLine7b() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(0,0);
path.lineTo(4,0);
path.close();
@@ -138,7 +138,7 @@
}
static void testLine8() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(0,4);
path.lineTo(4,4);
path.lineTo(2,2);
@@ -151,7 +151,7 @@
}
static void testLine9() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(0,4);
path.lineTo(4,4);
path.lineTo(2,2);
@@ -164,7 +164,7 @@
}
static void testLine10() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(0,4);
path.lineTo(4,4);
path.lineTo(2,2);
@@ -177,7 +177,7 @@
}
static void testLine10a() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(0,4);
path.lineTo(8,4);
path.lineTo(4,0);
@@ -218,90 +218,90 @@
}
static void testLine11() {
- SkPath path, simple;
+ SkPath path;
addCWContainer(path);
addCWContents(path);
testSimplifyx(path);
}
static void testLine12() {
- SkPath path, simple;
+ SkPath path;
addCCWContainer(path);
addCWContents(path);
testSimplifyx(path);
}
static void testLine13() {
- SkPath path, simple;
+ SkPath path;
addCWContainer(path);
addCCWContents(path);
testSimplifyx(path);
}
static void testLine14() {
- SkPath path, simple;
+ SkPath path;
addCCWContainer(path);
addCCWContents(path);
testSimplifyx(path);
}
static void testLine15() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine16() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 4, 9, 9, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine17() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine18() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(12, 4, 21, 21, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine19() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(12, 16, 21, 21, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine20() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 12, 9, 9, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine21() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 16, 9, 9, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine22() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine23() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
path.addRect(12, 0, 21, 21, (SkPath::Direction) 0);
testSimplifyx(path);
@@ -310,7 +310,7 @@
static void testLine24a() {
- SkPath path, simple;
+ SkPath path;
path.moveTo(2,0);
path.lineTo(4,4);
path.lineTo(0,4);
@@ -323,49 +323,49 @@
}
static void testLine24() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine25() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
path.addRect(12, 0, 21, 21, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine26() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 12, 9, 9, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine27() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
path.addRect(12, 8, 21, 21, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine28() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine29() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 18, 12, 12, (SkPath::Direction) 0);
path.addRect(12, 12, 21, 21, (SkPath::Direction) 0);
testSimplifyx(path);
}
static void testLine30() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(4, 4, 13, 13, (SkPath::Direction) 0);
@@ -373,7 +373,7 @@
}
static void testLine31() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 4, 9, 9, (SkPath::Direction) 0);
@@ -381,7 +381,7 @@
}
static void testLine32() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
@@ -389,7 +389,7 @@
}
static void testLine33() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
@@ -397,7 +397,7 @@
}
static void testLine34() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
path.addRect(4, 12, 13, 13, (SkPath::Direction) 0);
@@ -405,7 +405,7 @@
}
static void testLine35() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(6, 0, 18, 18, (SkPath::Direction) 0);
path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
@@ -413,7 +413,7 @@
}
static void testLine36() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 10, 20, 20, (SkPath::Direction) 0);
path.addRect(6, 12, 18, 18, (SkPath::Direction) 0);
path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
@@ -421,7 +421,7 @@
}
static void testLine37() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
path.addRect(18, 24, 30, 30, (SkPath::Direction) 0);
path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
@@ -429,7 +429,7 @@
}
static void testLine38() {
- SkPath path, simple;
+ SkPath path;
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
path.addRect(6, 12, 18, 18, (SkPath::Direction) 0);
path.addRect(12, 12, 21, 21, (SkPath::Direction) 0);
@@ -437,7 +437,7 @@
}
static void testLine40() {
- SkPath path, simple;
+ SkPath path;
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
path.addRect(12, 18, 24, 24, (SkPath::Direction) 0);
path.addRect(4, 16, 13, 13, (SkPath::Direction) 0);
@@ -445,7 +445,7 @@
}
static void testLine41() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(18, 24, 30, 30, (SkPath::Direction) 0);
path.addRect(12, 0, 21, 21, (SkPath::Direction) 0);
@@ -453,7 +453,7 @@
}
static void testLine42() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(8, 16, 17, 17, (SkPath::Direction) 0);
@@ -461,7 +461,7 @@
}
static void testLine43() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(6, 24, 18, 18, (SkPath::Direction) 0);
path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
@@ -469,7 +469,7 @@
}
static void testLine44() {
- SkPath path, simple;
+ SkPath path;
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
path.addRect(18, 0, 30, 30, (SkPath::Direction) 0);
path.addRect(18, 32, 27, 36, (SkPath::Direction) 1);
@@ -477,7 +477,7 @@
}
static void testLine45() {
- SkPath path, simple;
+ SkPath path;
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
path.addRect(18, 0, 30, 30, (SkPath::Direction) 0);
path.addRect(24, 32, 33, 36, (SkPath::Direction) 0);
@@ -485,7 +485,7 @@
}
static void testLine46() {
- SkPath path, simple;
+ SkPath path;
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
path.addRect(24, 0, 36, 36, (SkPath::Direction) 0);
path.addRect(24, 32, 33, 36, (SkPath::Direction) 0);
@@ -493,7 +493,7 @@
}
static void testLine47() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
@@ -501,7 +501,7 @@
}
static void testLine48() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 6, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 0, 9, 9, (SkPath::Direction) 1);
@@ -509,7 +509,7 @@
}
static void testLine49() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 0, 12, 12, (SkPath::Direction) 0);
path.addRect(0, 0, 9, 9, (SkPath::Direction) 0);
@@ -517,7 +517,7 @@
}
static void testLine50() {
- SkPath path, simple;
+ SkPath path;
path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
path.addRect(24, 20, 36, 30, (SkPath::Direction) 0);
testSimplifyx(path);
@@ -525,7 +525,7 @@
static void testLine51() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
@@ -533,7 +533,7 @@
}
static void testLine52() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 30, 20, 20, (SkPath::Direction) 0);
path.addRect(6, 20, 18, 30, (SkPath::Direction) 0);
path.addRect(32, 0, 36, 41, (SkPath::Direction) 0);
@@ -541,7 +541,7 @@
}
static void testLine53() {
- SkPath path, simple;
+ SkPath path;
path.addRect(10, 30, 30, 30, (SkPath::Direction) 0);
path.addRect(12, 20, 24, 30, (SkPath::Direction) 0);
path.addRect(12, 32, 21, 36, (SkPath::Direction) 1);
@@ -549,7 +549,7 @@
}
static void testLine54() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(6, 0, 18, 18, (SkPath::Direction) 0);
path.addRect(8, 4, 17, 17, (SkPath::Direction) 1);
@@ -557,7 +557,7 @@
}
static void testLine55() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(6, 6, 18, 18, (SkPath::Direction) 0);
path.addRect(4, 4, 13, 13, (SkPath::Direction) 1);
@@ -565,7 +565,7 @@
}
static void testLine56() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
path.addRect(18, 20, 30, 30, (SkPath::Direction) 0);
path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
@@ -573,7 +573,7 @@
}
static void testLine57() {
- SkPath path, simple;
+ SkPath path;
path.addRect(20, 0, 40, 40, (SkPath::Direction) 0);
path.addRect(20, 0, 30, 40, (SkPath::Direction) 0);
path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
@@ -581,7 +581,7 @@
}
static void testLine58() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 0, 12, 12, (SkPath::Direction) 1);
path.addRect(0, 12, 9, 9, (SkPath::Direction) 1);
@@ -589,7 +589,7 @@
}
static void testLine59() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(6, 6, 18, 18, (SkPath::Direction) 1);
path.addRect(4, 4, 13, 13, (SkPath::Direction) 1);
@@ -597,7 +597,7 @@
}
static void testLine60() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(6, 12, 18, 18, (SkPath::Direction) 1);
path.addRect(4, 12, 13, 13, (SkPath::Direction) 1);
@@ -605,7 +605,7 @@
}
static void testLine61() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(12, 0, 24, 24, (SkPath::Direction) 1);
path.addRect(12, 0, 21, 21, (SkPath::Direction) 1);
@@ -613,7 +613,7 @@
}
static void testLine62() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 12, 12, 12, (SkPath::Direction) 0);
@@ -622,7 +622,7 @@
}
static void testLine63() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(0, 10, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 6, 12, 12, (SkPath::Direction) 1);
@@ -631,7 +631,7 @@
}
static void testLine64() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
path.addRect(18, 6, 30, 30, (SkPath::Direction) 0);
@@ -639,7 +639,7 @@
}
static void testLine65() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(10, 0, 30, 30, (SkPath::Direction) 0);
path.addRect(24, 0, 36, 36, (SkPath::Direction) 0);
@@ -648,7 +648,7 @@
}
static void testLine66() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(0, 30, 20, 20, (SkPath::Direction) 0);
path.addRect(12, 20, 24, 30, (SkPath::Direction) 0);
@@ -656,7 +656,7 @@
}
static void testLine67() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
path.addRect(24, 20, 36, 30, (SkPath::Direction) 0);
@@ -665,7 +665,7 @@
}
static void testLine68a() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 0);
path.addRect(1, 2, 4, 2, (SkPath::Direction) 0);
@@ -673,7 +673,7 @@
}
static void testLine68b() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
path.addRect(1, 2, 2, 2, (SkPath::Direction) 0);
@@ -681,7 +681,7 @@
}
static void testLine68c() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 8, 8, (SkPath::Direction) 1);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 0);
path.addRect(1, 2, 4, 2, (SkPath::Direction) 0);
@@ -689,7 +689,7 @@
}
static void testLine68d() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 8, 8, (SkPath::Direction) 1);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
path.addRect(1, 2, 4, 2, (SkPath::Direction) 0);
@@ -697,7 +697,7 @@
}
static void testLine68e() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
@@ -706,7 +706,7 @@
}
static void testLine68f() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
@@ -715,7 +715,7 @@
}
static void testLine68g() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
@@ -725,7 +725,7 @@
}
static void testLine68h() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 8, 8, (SkPath::Direction) 0);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
path.addRect(2, 2, 6, 6, (SkPath::Direction) 1);
@@ -735,7 +735,7 @@
}
static void testLine69() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 20, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 20, 12, 30, (SkPath::Direction) 0);
path.addRect(12, 32, 21, 36, (SkPath::Direction) 0);
@@ -743,7 +743,7 @@
}
static void testLine70() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 24, 12, 12, (SkPath::Direction) 0);
path.addRect(12, 32, 21, 36, (SkPath::Direction) 1);
@@ -751,7 +751,7 @@
}
static void testLine71() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 20, 20, (SkPath::Direction) 0);
path.addRect(12, 0, 24, 24, (SkPath::Direction) 0);
path.addRect(12, 32, 21, 36, (SkPath::Direction) 0);
@@ -759,7 +759,7 @@
}
static void testLine72() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(10, 40, 30, 30, (SkPath::Direction) 0);
path.addRect(6, 20, 18, 30, (SkPath::Direction) 0);
@@ -767,7 +767,7 @@
}
static void testLine73() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(0, 40, 20, 20, (SkPath::Direction) 0);
path.addRect(0, 20, 12, 30, (SkPath::Direction) 0);
@@ -776,7 +776,7 @@
}
static void testLine74() {
- SkPath path, simple;
+ SkPath path;
path.addRect(20, 30, 40, 40, (SkPath::Direction) 0);
path.addRect(24, 20, 36, 30, (SkPath::Direction) 1);
path.addRect(32, 24, 36, 41, (SkPath::Direction) 1);
@@ -784,7 +784,7 @@
}
static void testLine75() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 60, 60, (SkPath::Direction) 0);
path.addRect(10, 0, 30, 30, (SkPath::Direction) 1);
path.addRect(18, 0, 30, 30, (SkPath::Direction) 1);
@@ -793,7 +793,7 @@
}
static void testLine76() {
- SkPath path, simple;
+ SkPath path;
path.addRect(36, 0, 66, 60, (SkPath::Direction) 0);
path.addRect(10, 20, 40, 30, (SkPath::Direction) 0);
path.addRect(24, 20, 36, 30, (SkPath::Direction) 1);
@@ -802,7 +802,7 @@
}
static void testLine77() {
- SkPath path, simple;
+ SkPath path;
path.addRect(20, 0, 40, 40, (SkPath::Direction) 0);
path.addRect(24, 6, 36, 36, (SkPath::Direction) 1);
path.addRect(24, 32, 33, 36, (SkPath::Direction) 1);
@@ -810,7 +810,7 @@
}
static void testLine78() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 0, 30, 60, (SkPath::Direction) 0);
path.addRect(10, 20, 30, 30, (SkPath::Direction) 1);
path.addRect(18, 20, 30, 30, (SkPath::Direction) 1);
@@ -819,7 +819,7 @@
}
static void testLine79() {
- SkPath path, simple;
+ SkPath path;
path.addRect(0, 36, 60, 30, (SkPath::Direction) 0);
path.addRect(10, 30, 40, 30, (SkPath::Direction) 0);
path.addRect(0, 20, 12, 30, (SkPath::Direction) 1);
@@ -827,12 +827,156 @@
testSimplifyx(path);
}
+static void testDegenerate1() {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(2, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 0);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testDegenerate2() {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(0, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(0, 1);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testDegenerate3() {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(2, 0);
+ path.lineTo(1, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(3, 0);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testDegenerate4() {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 1);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testNondegenerate1() {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 1);
+ path.lineTo(2, 1);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testNondegenerate2() {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 2);
+ path.lineTo(0, 3);
+ path.lineTo(1, 2);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testNondegenerate3() {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(0, 1);
+ path.lineTo(1, 1);
+ path.lineTo(0, 2);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testNondegenerate4() {
+ SkPath path;
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 2);
+ path.lineTo(0, 3);
+ path.lineTo(1, 3);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testQuadralateral5() {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 2);
+ path.lineTo(3, 2);
+ path.lineTo(3, 3);
+ path.close();
+ testSimplifyx(path);
+}
+
+static void testQuadralateral6() {
+ SkPath path;
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.lineTo(0, 2);
+ path.lineTo(2, 2);
+ path.close();
+ testSimplifyx(path);
+}
+
static void (*firstTest)() = 0;
static struct {
void (*fun)();
const char* str;
} tests[] = {
+ TEST(testQuadralateral6),
+ TEST(testQuadralateral5),
+ TEST(testNondegenerate4),
+ TEST(testNondegenerate3),
+ TEST(testNondegenerate2),
+ TEST(testNondegenerate1),
+ TEST(testDegenerate4),
+ TEST(testDegenerate3),
+ TEST(testDegenerate2),
+ TEST(testDegenerate1),
TEST(testLine79),
TEST(testLine78),
TEST(testLine77),
@@ -968,7 +1112,9 @@
while (index > 0 && tests[index].fun != firstTest) {
--index;
}
+ (*tests[index].fun)();
}
+ index = testCount - 1;
bool firstTestComplete = false;
do {
SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str);
diff --git a/experimental/Intersection/SimplifyRect4x4_Test.cpp b/experimental/Intersection/SimplifyRect4x4_Test.cpp
index 3f8145b..6782d53 100644
--- a/experimental/Intersection/SimplifyRect4x4_Test.cpp
+++ b/experimental/Intersection/SimplifyRect4x4_Test.cpp
@@ -7,15 +7,6 @@
#include "EdgeWalker_Test.h"
#include "Intersection_Tests.h"
#include "ShapeOps.h"
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkStream.h"
-#include <assert.h>
-#include <errno.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/sysctl.h>
// four rects, of four sizes
// for 3 smaller sizes, tall, wide
@@ -23,211 +14,151 @@
// same with x (3 bits, 5 values)
// not included, square, tall, wide (2 bits)
// cw or ccw (1 bit)
-static const char marker[] =
- "</div>\n"
- "\n"
- "<script type=\"text/javascript\">\n"
- "\n"
- "var testDivs = [\n";
-static const char testLineStr[] = " testLine";
-#if 0
-static const char filename[] = "../../experimental/Intersection/debugXX.txt";
-#else
-static const char filename[] = "/flash/debug/XX.txt";
-#endif
-static int testNumber;
-
-#define BETTER_THREADS 01
-#define DEBUG_BETTER_THREADS 0
static void* testSimplify4x4RectsMain(void* data)
{
SkASSERT(data);
State4& state = *(State4*) data;
-#if BETTER_THREADS
- do {
-#endif
char pathStr[1024]; // gdb: set print elements 400
bzero(pathStr, sizeof(pathStr));
- state.testsRun = 0;
- int aShape = state.a & 0x03;
- int aCW = state.a >> 2;
- int bShape = state.b & 0x03;
- int bCW = state.b >> 2;
- int cShape = state.c & 0x03;
- int cCW = state.c >> 2;
- int dShape = state.d & 0x03;
- int dCW = state.d >> 2;
- for (int aXAlign = 0 ; aXAlign < 5; ++aXAlign) {
- for (int aYAlign = 0 ; aYAlign < 5; ++aYAlign) {
- for (int bXAlign = 0 ; bXAlign < 5; ++bXAlign) {
- for (int bYAlign = 0 ; bYAlign < 5; ++bYAlign) {
- for (int cXAlign = 0 ; cXAlign < 5; ++cXAlign) {
- for (int cYAlign = 0 ; cYAlign < 5; ++cYAlign) {
- for (int dXAlign = 0 ; dXAlign < 5; ++dXAlign) {
- for (int dYAlign = 0 ; dYAlign < 5; ++dYAlign) {
- SkPath path, out;
- char* str = pathStr;
- path.setFillType(SkPath::kWinding_FillType);
- int l, t, r, b;
- if (aShape) {
- switch (aShape) {
- case 1: // square
- l = 0; r = 60;
- t = 0; b = 60;
- aXAlign = 5;
- aYAlign = 5;
- break;
- case 2:
- l = aXAlign * 12;
- r = l + 30;
- t = 0; b = 60;
- aYAlign = 5;
- break;
- case 3:
- l = 0; r = 60;
- t = aYAlign * 12;
- b = l + 30;
- aXAlign = 5;
- break;
+ do {
+ int aShape = state.a & 0x03;
+ int aCW = state.a >> 2;
+ int bShape = state.b & 0x03;
+ int bCW = state.b >> 2;
+ int cShape = state.c & 0x03;
+ int cCW = state.c >> 2;
+ int dShape = state.d & 0x03;
+ int dCW = state.d >> 2;
+ for (int aXAlign = 0 ; aXAlign < 5; ++aXAlign) {
+ for (int aYAlign = 0 ; aYAlign < 5; ++aYAlign) {
+ for (int bXAlign = 0 ; bXAlign < 5; ++bXAlign) {
+ for (int bYAlign = 0 ; bYAlign < 5; ++bYAlign) {
+ for (int cXAlign = 0 ; cXAlign < 5; ++cXAlign) {
+ for (int cYAlign = 0 ; cYAlign < 5; ++cYAlign) {
+ for (int dXAlign = 0 ; dXAlign < 5; ++dXAlign) {
+ for (int dYAlign = 0 ; dYAlign < 5; ++dYAlign) {
+ SkPath path, out;
+ char* str = pathStr;
+ path.setFillType(SkPath::kWinding_FillType);
+ int l, t, r, b;
+ if (aShape) {
+ switch (aShape) {
+ case 1: // square
+ l = 0; r = 60;
+ t = 0; b = 60;
+ aXAlign = 5;
+ aYAlign = 5;
+ break;
+ case 2:
+ l = aXAlign * 12;
+ r = l + 30;
+ t = 0; b = 60;
+ aYAlign = 5;
+ break;
+ case 3:
+ l = 0; r = 60;
+ t = aYAlign * 12;
+ b = l + 30;
+ aXAlign = 5;
+ break;
+ }
+ path.addRect(l, t, r, b, (SkPath::Direction) aCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " (SkPath::Direction) %d);\n", l, t, r, b, aCW);
+ } else {
+ aXAlign = 5;
+ aYAlign = 5;
}
- path.addRect(l, t, r, b, (SkPath::Direction) aCW);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " (SkPath::Direction) %d);\n", l, t, r, b, aCW);
- } else {
- aXAlign = 5;
- aYAlign = 5;
- }
- if (bShape) {
- switch (bShape) {
- case 1: // square
- l = bXAlign * 10;
- r = l + 20;
- t = bYAlign * 10;
- b = l + 20;
- break;
- case 2:
- l = bXAlign * 10;
- r = l + 20;
- t = 10; b = 40;
- bYAlign = 5;
- break;
- case 3:
- l = 10; r = 40;
- t = bYAlign * 10;
- b = l + 20;
- bXAlign = 5;
- break;
+ if (bShape) {
+ switch (bShape) {
+ case 1: // square
+ l = bXAlign * 10;
+ r = l + 20;
+ t = bYAlign * 10;
+ b = l + 20;
+ break;
+ case 2:
+ l = bXAlign * 10;
+ r = l + 20;
+ t = 10; b = 40;
+ bYAlign = 5;
+ break;
+ case 3:
+ l = 10; r = 40;
+ t = bYAlign * 10;
+ b = l + 20;
+ bXAlign = 5;
+ break;
+ }
+ path.addRect(l, t, r, b, (SkPath::Direction) bCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " (SkPath::Direction) %d);\n", l, t, r, b, bCW);
+ } else {
+ bXAlign = 5;
+ bYAlign = 5;
}
- path.addRect(l, t, r, b, (SkPath::Direction) bCW);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " (SkPath::Direction) %d);\n", l, t, r, b, bCW);
- } else {
- bXAlign = 5;
- bYAlign = 5;
- }
- if (cShape) {
- switch (cShape) {
- case 1: // square
- l = cXAlign * 6;
- r = l + 12;
- t = cYAlign * 6;
- b = l + 12;
- break;
- case 2:
- l = cXAlign * 6;
- r = l + 12;
- t = 20; b = 30;
- cYAlign = 5;
- break;
- case 3:
- l = 20; r = 30;
- t = cYAlign * 6;
- b = l + 20;
- cXAlign = 5;
- break;
+ if (cShape) {
+ switch (cShape) {
+ case 1: // square
+ l = cXAlign * 6;
+ r = l + 12;
+ t = cYAlign * 6;
+ b = l + 12;
+ break;
+ case 2:
+ l = cXAlign * 6;
+ r = l + 12;
+ t = 20; b = 30;
+ cYAlign = 5;
+ break;
+ case 3:
+ l = 20; r = 30;
+ t = cYAlign * 6;
+ b = l + 20;
+ cXAlign = 5;
+ break;
+ }
+ path.addRect(l, t, r, b, (SkPath::Direction) cCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " (SkPath::Direction) %d);\n", l, t, r, b, cCW);
+ } else {
+ cXAlign = 5;
+ cYAlign = 5;
}
- path.addRect(l, t, r, b, (SkPath::Direction) cCW);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " (SkPath::Direction) %d);\n", l, t, r, b, cCW);
- } else {
- cXAlign = 5;
- cYAlign = 5;
- }
- if (dShape) {
- switch (dShape) {
- case 1: // square
- l = dXAlign * 4;
- r = l + 9;
- t = dYAlign * 4;
- b = l + 9;
- break;
- case 2:
- l = dXAlign * 6;
- r = l + 9;
- t = 32; b = 36;
- dYAlign = 5;
- break;
- case 3:
- l = 32; r = 36;
- t = dYAlign * 6;
- b = l + 9;
- dXAlign = 5;
- break;
+ if (dShape) {
+ switch (dShape) {
+ case 1: // square
+ l = dXAlign * 4;
+ r = l + 9;
+ t = dYAlign * 4;
+ b = l + 9;
+ break;
+ case 2:
+ l = dXAlign * 6;
+ r = l + 9;
+ t = 32; b = 36;
+ dYAlign = 5;
+ break;
+ case 3:
+ l = 32; r = 36;
+ t = dYAlign * 6;
+ b = l + 9;
+ dXAlign = 5;
+ break;
+ }
+ path.addRect(l, t, r, b, (SkPath::Direction) dCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " (SkPath::Direction) %d);\n", l, t, r, b, dCW);
+ } else {
+ dXAlign = 5;
+ dYAlign = 5;
}
- path.addRect(l, t, r, b, (SkPath::Direction) dCW);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " (SkPath::Direction) %d);\n", l, t, r, b, dCW);
- } else {
- dXAlign = 5;
- dYAlign = 5;
- }
- path.close();
- if (gRunTestsInOneThread) {
- SkDebugf("%s\n", pathStr);
- } else {
- #if 0
- char pwd[1024];
- getcwd(pwd, sizeof(pwd));
- SkDebugf("%s\n", pwd);
- #endif
- #if 1
- SkFILEWStream outFile(state.filename);
- if (!outFile.isValid()) {
- continue;
- }
- outFile.writeText("<div id=\"testLine");
- outFile.writeDecAsText(testNumber);
- outFile.writeText("\">\n");
- outFile.writeText(pathStr);
- outFile.writeText("</div>\n\n");
-
- outFile.writeText(marker);
- outFile.writeText(testLineStr);
- outFile.writeDecAsText(testNumber);
- outFile.writeText(",\n\n\n");
-
- outFile.writeText("static void testLine");
- outFile.writeDecAsText(testNumber);
- outFile.writeText("() {\n SkPath path, simple;\n");
- outFile.writeText(pathStr);
- outFile.writeText(" testSimplifyx(path);\n}\n\n");
- outFile.writeText("static void (*firstTest)() = testLine");
- outFile.writeDecAsText(testNumber);
- outFile.writeText(";\n\n");
-
- outFile.writeText("static struct {\n");
- outFile.writeText(" void (*fun)();\n");
- outFile.writeText(" const char* str;\n");
- outFile.writeText("} tests[] = {\n");
- outFile.writeText(" TEST(testLine");
- outFile.writeDecAsText(testNumber);
- outFile.writeText("),\n");
- outFile.flush();
- #endif
- }
- testSimplifyx(path, out, state.bitmap, state.canvas);
- state.testsRun++;
+ path.close();
+ outputProgress(state, pathStr);
+ testSimplifyx(path, out, state, pathStr);
+ state.testsRun++;
+ }
}
}
}
@@ -235,176 +166,33 @@
}
}
}
- }
- if (gRunTestsInOneThread) {
- return NULL;
- }
-#if BETTER_THREADS
- if (DEBUG_BETTER_THREADS) SkDebugf("%s done %d\n", __FUNCTION__, state.index);
- pthread_mutex_lock(&State4::addQueue);
- if (DEBUG_BETTER_THREADS) SkDebugf("%s lock %d\n", __FUNCTION__, state.index);
- state.next = State4::queue ? State4::queue->next : NULL;
- state.done = true;
- State4::queue = &state;
- pthread_cond_signal(&State4::checkQueue);
- while (state.done && !state.last) {
- if (DEBUG_BETTER_THREADS) SkDebugf("%s wait %d\n", __FUNCTION__, state.index);
- pthread_cond_wait(&state.initialized, &State4::addQueue);
- if (DEBUG_BETTER_THREADS) SkDebugf("%s wait done %d\n", __FUNCTION__, state.index);
- }
- pthread_mutex_unlock(&State4::addQueue);
- if (DEBUG_BETTER_THREADS) SkDebugf("%s unlock %d\n", __FUNCTION__, state.index);
-} while (!state.last);
-#endif
+ } while (runNextTestSet(state));
return NULL;
}
-const int maxThreadsAllocated = 64;
-
-State4* State4::queue = NULL;
-pthread_mutex_t State4::addQueue = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t State4::checkQueue = PTHREAD_COND_INITIALIZER;
-
void Simplify4x4RectsThreaded_Test()
{
+ SkDebugf("%s\n", __FUNCTION__);
#ifdef SK_DEBUG
gDebugMaxWindSum = 4;
gDebugMaxWindValue = 4;
#endif
- int maxThreads = 1;
- if (!gRunTestsInOneThread) {
- int threads = -1;
- size_t size = sizeof(threads);
- sysctlbyname("hw.logicalcpu_max", &threads, &size, NULL, 0);
- SkDebugf("%s errno=%d size=%d processors=%d\n", __FUNCTION__,
- errno, size, threads);
- if (threads > 0) {
- maxThreads = threads;
- } else {
- maxThreads = 8;
- }
- SkDebugf("%s maxThreads=%d\n", __FUNCTION__, maxThreads);
- }
- if (!gRunTestsInOneThread) {
- SkFILEStream inFile("../../experimental/Intersection/op.htm");
- if (inFile.isValid()) {
- SkTDArray<char> inData;
- inData.setCount(inFile.getLength());
- size_t inLen = inData.count();
- inFile.read(inData.begin(), inLen);
- inFile.setPath(NULL);
- char* insert = strstr(inData.begin(), marker);
- if (insert) {
- insert += sizeof(marker) - 1;
- const char* numLoc = insert + sizeof(testLineStr) - 1;
- testNumber = atoi(numLoc) + 1;
- }
- }
- }
- State4 threadState[maxThreadsAllocated];
- int threadIndex;
- for (threadIndex = 0; threadIndex < maxThreads; ++threadIndex) {
- State4* statePtr = &threadState[threadIndex];
- strcpy(statePtr->filename, filename);
- SkASSERT(statePtr->filename[sizeof(filename) - 7] == 'X');
- SkASSERT(statePtr->filename[sizeof(filename) - 6] == 'X');
- statePtr->filename[sizeof(filename) - 7] = '0' + threadIndex / 10;
- statePtr->filename[sizeof(filename) - 6] = '0' + threadIndex % 10;
- }
- threadIndex = 0;
+ const char testLineStr[] = "testLine";
+ initializeTests(testLineStr, sizeof(testLineStr));
int testsRun = 0;
for (int a = 0; a < 8; ++a) { // outermost
for (int b = a ; b < 8; ++b) {
for (int c = b ; c < 8; ++c) {
for (int d = c; d < 8; ++d) {
- if (!gRunTestsInOneThread) {
- #if BETTER_THREADS == 0
- State4* statePtr = &threadState[threadIndex];
- statePtr->a = a;
- statePtr->b = b;
- statePtr->c = c;
- statePtr->d = d;
- createThread(statePtr, testSimplify4x4RectsMain);
- if (++threadIndex >= maxThreads) {
- waitForCompletion(threadState, threadIndex);
- for (int index = 0; index < maxThreads; ++index) {
- testsRun += threadState[index].testsRun;
- }
- }
- #else
- State4* statePtr;
- pthread_mutex_lock(&State4::addQueue);
- if (threadIndex < maxThreads) {
- statePtr = &threadState[threadIndex];
- statePtr->a = a;
- statePtr->b = b;
- statePtr->c = c;
- statePtr->d = d;
- statePtr->index = threadIndex;
- statePtr->done = false;
- statePtr->last = false;
- pthread_cond_init(&statePtr->initialized, NULL);
- ++threadIndex;
- createThread(statePtr, testSimplify4x4RectsMain);
- } else {
- while (!State4::queue) {
- if (DEBUG_BETTER_THREADS) SkDebugf("%s wait\n", __FUNCTION__);
- pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
- }
- statePtr = State4::queue;
- testsRun += statePtr->testsRun;
- if (DEBUG_BETTER_THREADS) SkDebugf("%s dequeue %d\n", __FUNCTION__, statePtr->index);
- statePtr->a = a;
- statePtr->b = b;
- statePtr->c = c;
- statePtr->d = d;
- statePtr->done = false;
- State4::queue = State4::queue->next;
- pthread_cond_signal(&statePtr->initialized);
- }
- pthread_mutex_unlock(&State4::addQueue);
- #endif
- } else {
- State4 state;
- state.a = a;
- state.b = b;
- state.c = c;
- state.d = d;
- testSimplify4x4RectsMain(&state);
- }
- if (!gRunTestsInOneThread) SkDebugf(".");
+ testsRun += dispatchTest4(testSimplify4x4RectsMain, a, b, c, d);
}
- if (!gRunTestsInOneThread) SkDebugf("%d", c);
+ if (!gRunTestsInOneThread) SkDebugf(".");
}
- if (!gRunTestsInOneThread) SkDebugf("\n%d", b);
+ if (!gRunTestsInOneThread) SkDebugf("%d", b);
}
- if (!gRunTestsInOneThread) SkDebugf("\n\n%d", a);
+ if (!gRunTestsInOneThread) SkDebugf("\n%d", a);
}
- if (!gRunTestsInOneThread) {
- pthread_mutex_lock(&State4::addQueue);
- int runningThreads = maxThreads;
- while (runningThreads > 0) {
- while (!State4::queue) {
- if (DEBUG_BETTER_THREADS) SkDebugf("%s wait\n", __FUNCTION__);
- pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
- }
- while (State4::queue) {
- State4::queue->last = true;
- pthread_cond_signal(&State4::queue->initialized);
- State4::queue = State4::queue->next;
- --runningThreads;
- }
- }
- pthread_mutex_unlock(&State4::addQueue);
- for (threadIndex = 0; threadIndex < maxThreads; ++threadIndex) {
- pthread_join(threadState[threadIndex].threadID, NULL);
- testsRun += threadState[threadIndex].testsRun;
- }
- SkDebugf("%s total tests run=%d\n", __FUNCTION__, testsRun);
- }
-#ifdef SK_DEBUG
- gDebugMaxWindSum = SK_MaxS32;
- gDebugMaxWindValue = SK_MaxS32;
-#endif
+ testsRun += waitForCompletion();
+ SkDebugf("%s total tests run=%d\n", __FUNCTION__, testsRun);
}
diff --git a/experimental/Intersection/op.htm b/experimental/Intersection/op.htm
index c4a465d..ce40130 100644
--- a/experimental/Intersection/op.htm
+++ b/experimental/Intersection/op.htm
@@ -748,11 +748,135 @@
path.addRect(0, 32, 9, 36, (SkPath::Direction) 1);
</div>
+<div id="testDegenerate1">
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(2, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 0);
+ path.close();
+</div>
+
+<div id="testDegenerate2">
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(0, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(0, 1);
+ path.close();
+</div>
+
+<div id="testDegenerate3">
+ path.moveTo(0, 0);
+ path.lineTo(2, 0);
+ path.lineTo(1, 0);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(3, 0);
+ path.close();
+</div>
+
+<div id="testDegenerate4">
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(1, 1);
+ path.lineTo(1, 2);
+ path.close();
+</div>
+
+<div id="testNondegenerate1">
+ path.moveTo(0, 0);
+ path.lineTo(3, 0);
+ path.lineTo(1, 3);
+ path.close();
+ path.moveTo(1, 1);
+ path.lineTo(2, 1);
+ path.lineTo(1, 2);
+ path.close();
+</div>
+
+<div id="testNondegenerate2">
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 2);
+ path.lineTo(0, 3);
+ path.lineTo(1, 2);
+ path.close();
+</div>
+
+<div id="testNondegenerate3">
+ path.moveTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(2, 1);
+ path.close();
+ path.moveTo(0, 1);
+ path.lineTo(1, 1);
+ path.lineTo(0, 2);
+ path.close();
+</div>
+
+<div id="testNondegenerate4">
+ path.moveTo(1, 0);
+ path.lineTo(0, 1);
+ path.lineTo(1, 2);
+ path.close();
+ path.moveTo(0, 2);
+ path.lineTo(0, 3);
+ path.lineTo(1, 3);
+ path.close();
+</div>
+
+<div id="testQuadralateral5">
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(0, 0);
+ path.lineTo(2, 2);
+ path.lineTo(3, 2);
+ path.lineTo(3, 3);
+ path.close();
+</div>
+
+<div id="testQuadralateral6">
+ path.moveTo(0, 0);
+ path.lineTo(0, 0);
+ path.lineTo(1, 0);
+ path.lineTo(1, 1);
+ path.close();
+ path.moveTo(1, 0);
+ path.lineTo(2, 0);
+ path.lineTo(0, 2);
+ path.lineTo(2, 2);
+ path.close();
+</div>
+
</div>
<script type="text/javascript">
var testDivs = [
+ testQuadralateral6,
+ testQuadralateral5,
+ testNondegenerate4,
+ testNondegenerate3,
+ testNondegenerate2,
+ testNondegenerate1,
+ testDegenerate4,
+ testDegenerate3,
+ testDegenerate2,
+ testDegenerate1,
testLine79,
testLine78,
testLine77,