aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-04-10 15:55:37 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-04-10 15:55:37 +0000
commit66089e4ec4f1702caf2154780471417872862148 (patch)
treee078d7a335a396cc325f2d2f55723315307eb07d
parent51dbabee67ea1285e1115e535d26944d4da99be5 (diff)
Make parallel unit testing work on windows
Review URL: https://codereview.chromium.org/14072002 git-svn-id: http://skia.googlecode.com/svn/trunk@8594 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--gyp/pathops_unittest.gyp2
-rw-r--r--src/pathops/SkPathOpsDebug.h5
-rw-r--r--tests/PathOpsCubicIntersectionTestData.cpp37
-rw-r--r--tests/PathOpsCubicIntersectionTestData.h2
-rw-r--r--tests/PathOpsExtendedTest.cpp416
-rw-r--r--tests/PathOpsExtendedTest.h74
-rw-r--r--tests/PathOpsOpCubicThreadedTest.cpp108
-rw-r--r--tests/PathOpsOpRectThreadedTest.cpp113
-rw-r--r--tests/PathOpsQuadLineIntersectionThreadedTest.cpp87
-rwxr-xr-xtests/PathOpsSimplifyDegenerateThreadedTest.cpp120
-rw-r--r--tests/PathOpsSimplifyQuadThreadedTest.cpp127
-rwxr-xr-xtests/PathOpsSimplifyQuadralateralsThreadedTest.cpp132
-rw-r--r--tests/PathOpsSimplifyRectThreadedTest.cpp309
-rwxr-xr-xtests/PathOpsSimplifyTrianglesThreadedTest.cpp122
-rw-r--r--tests/PathOpsThreadedCommon.cpp29
-rw-r--r--tests/PathOpsThreadedCommon.h79
16 files changed, 728 insertions, 1034 deletions
diff --git a/gyp/pathops_unittest.gyp b/gyp/pathops_unittest.gyp
index 44ed3364a5..d3bb3bc862 100644
--- a/gyp/pathops_unittest.gyp
+++ b/gyp/pathops_unittest.gyp
@@ -106,10 +106,12 @@
'../tests/PathOpsSimplifyTest.cpp',
'../tests/PathOpsSimplifyTrianglesThreadedTest.cpp',
'../tests/PathOpsTestCommon.cpp',
+ '../tests/PathOpsThreadedCommon.cpp',
'../tests/PathOpsCubicIntersectionTestData.h',
'../tests/PathOpsExtendedTest.h',
'../tests/PathOpsQuadIntersectionTestData.h',
'../tests/PathOpsTestCommon.h',
+ '../tests/PathOpsThreadedCommon.h',
'../tests/Test.cpp',
'../tests/skia_test.cpp',
'../tests/Test.h',
diff --git a/src/pathops/SkPathOpsDebug.h b/src/pathops/SkPathOpsDebug.h
index 9735112689..53991bc642 100644
--- a/src/pathops/SkPathOpsDebug.h
+++ b/src/pathops/SkPathOpsDebug.h
@@ -18,8 +18,6 @@
#define ONE_OFF_DEBUG 0
#define ONE_OFF_DEBUG_MATHEMATICA 0
-#if defined SK_DEBUG || !FORCE_RELEASE
-
#ifdef SK_BUILD_FOR_WIN
#define SK_RAND(seed) rand()
#define SK_SNPRINTF _snprintf
@@ -28,12 +26,15 @@
#define SK_SNPRINTF snprintf
#endif
+#if defined SK_DEBUG || !FORCE_RELEASE
+
void mathematica_ize(char* str, size_t bufferSize);
bool valid_wind(int winding);
void winding_printf(int winding);
extern int gDebugMaxWindSum;
extern int gDebugMaxWindValue;
+
#endif
#if FORCE_RELEASE
diff --git a/tests/PathOpsCubicIntersectionTestData.cpp b/tests/PathOpsCubicIntersectionTestData.cpp
index 04c46d5267..f4c0b4a3ed 100644
--- a/tests/PathOpsCubicIntersectionTestData.cpp
+++ b/tests/PathOpsCubicIntersectionTestData.cpp
@@ -97,43 +97,16 @@ const SkDCubic tests[][2] = {
}, {
{{{125.79356, 199.57382}, {51.16556, 128.93575}, {87.494, 16.67848}, {167.29361, 16.67848}}},
{{{167.29361, 55.81876}, {100.36128, 55.81876}, {68.64099, 145.4755}, {125.7942, 199.57309}}}
+ }, {
+ {{{104.11546583642826, 370.21352558595504}, {122.96968232592344, 404.54489231839295},
+ {169.90881005384728, 425.00067000000007}, {221.33045999999999, 425.00067000000001}}},
+ {{{116.32365976159625, 381.71048540582598}, {103.86096590870899, 381.71048540581626},
+ {91.394188003200725, 377.17917781762833}, {82.622283093355179, 368.11683661930334}}}
}
};
const size_t tests_count = sizeof(tests) / sizeof(tests[0]);
-SkDCubic hexTests[][2] = {
- {
- // placeholder for hex converted below
- {{{0, 0}, {0, 0}, {0, 0}, {0, 0}}}, {{{0, 0}, {0, 0}, {0, 0}, {0, 0}}}
- }
-};
-
-const size_t hexTests_count = sizeof(hexTests) / sizeof(hexTests[0]);
-
-static const uint64_t testx[2][8] = {
- {
- 0xf0d0d1ca63075a40LLU, 0x9408ce996a237740LLU, 0x6d5675460fbe5e40LLU, 0x6ef501e1b7487940LLU,
- 0x9a71d2f8143d6540LLU, 0x6bc18bbe02907a40LLU, 0x5b94d92093aa6b40LLU, 0x6ac18bbe02907a40LLU
- },
- {
- 0x92c56ed7b6145d40LLU, 0xede4f1255edb7740LLU, 0x1138c1101af75940LLU, 0x42e4f1255edb7740LLU,
- 0x408e51603ad95640LLU, 0x1e2e8fe9dd927740LLU, 0x1cb4777cd3a75440LLU, 0x212e1390de017740LLU
- }
-};
-
-void convert_testx() {
- const uint64_t* inPtr = testx[0];
- double* outPtr = &hexTests[sizeof(tests) / sizeof(tests[0]) - 1][0][0].fX;
- for (unsigned index = 0; index < sizeof(testx) / sizeof(testx[0][0]); ++index) {
- uint64_t input = *inPtr++;
- unsigned char* output = (unsigned char*) outPtr++;
- for (unsigned byte = 0; byte < sizeof(input); ++byte) {
- output[byte] = input >> (7 - byte) * 8;
- }
- }
-}
-
const SkDCubic lines[] = {
{{{0, 0}, {0, 0}, {0, 0}, {1, 0}}}, // 0: horizontal
{{{1, 0}, {0, 0}, {0, 0}, {0, 0}}},
diff --git a/tests/PathOpsCubicIntersectionTestData.h b/tests/PathOpsCubicIntersectionTestData.h
index 9e7ad7348e..e37d5716d3 100644
--- a/tests/PathOpsCubicIntersectionTestData.h
+++ b/tests/PathOpsCubicIntersectionTestData.h
@@ -11,8 +11,6 @@ extern const SkDCubic notPointDegenerates[];
extern const SkDCubic tests[][2];
extern SkDCubic hexTests[][2];
-extern void convert_testx();
-
extern const SkDCubic lines[];
extern const SkDCubic notLines[];
extern const SkDCubic modEpsilonLines[];
diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp
index 9415d5f6a7..cbf21b1ebd 100644
--- a/tests/PathOpsExtendedTest.cpp
+++ b/tests/PathOpsExtendedTest.cpp
@@ -6,6 +6,7 @@
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkMatrix.h"
@@ -16,9 +17,6 @@
#include <sys/sysctl.h>
#endif
-bool gShowTestProgress = false;
-bool gAllowExtendedTest = false;
-
static const char marker[] =
"</div>\n"
"\n"
@@ -37,17 +35,15 @@ static const char* opSuffixes[] = {
"d",
"i",
"u",
- "x",
+ "o",
};
static bool gShowPath = false;
static bool gComparePaths = true;
-static bool gShowOutputProgress = false;
static bool gComparePathsAssert = true;
static bool gPathStrAssert = true;
-static bool gUsePhysicalFiles = false;
-#if FORCE_RELEASE && !defined SK_BUILD_FOR_WIN
+#if FORCE_RELEASE
static bool gRunTestsInOneThread = false;
#else
static bool gRunTestsInOneThread = true;
@@ -120,15 +116,17 @@ void showPathData(const SkPath& path) {
case SkPath::kMove_Verb:
continue;
case SkPath::kLine_Verb:
- SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY);
+ SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0].fY,
+ pts[1].fX, pts[1].fY);
break;
case SkPath::kQuad_Verb:
SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n",
- pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
+ pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
break;
case SkPath::kCubic_Verb:
SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n",
- pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY, pts[3].fX, pts[3].fY);
+ pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY,
+ pts[3].fX, pts[3].fY);
break;
case SkPath::kClose_Verb:
break;
@@ -162,7 +160,7 @@ static void showPath(const SkPath& path, const char* str, const SkMatrix& scale)
SkPath scaled;
SkMatrix inverse;
bool success = scale.invert(&inverse);
- if (!success) {
+ if (!success) {
SkASSERT(0);
}
path.transform(inverse, &scaled);
@@ -330,7 +328,7 @@ static void showPathOpPath(const SkPath& one, const SkPath& two, const SkPath& a
static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const SkPath& scaledOne,
const SkPath& two, const SkPath& scaledTwo, SkBitmap& bitmap,
- const SkPath& a, const SkPath& b, const SkPathOp shapeOp,
+ const SkPath& a, const SkPath& b, const SkPathOp shapeOp,
const SkMatrix& scale) {
int errors2x2;
int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2);
@@ -349,7 +347,63 @@ static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S
return errors2x2 > MAX_ERRORS ? errors2x2 : 0;
}
-bool testSimplify(SkPath& path, bool useXor, SkPath& out, State4& state, const char* pathStr) {
+static int testNumber;
+static const char* testName;
+
+static void writeTestName(const char* nameSuffix, SkMemoryWStream& outFile) {
+ outFile.writeText(testName);
+ outFile.writeDecAsText(testNumber);
+ if (nameSuffix) {
+ outFile.writeText(nameSuffix);
+ }
+}
+
+static void outputToStream(const char* pathStr, const char* pathPrefix, const char* nameSuffix,
+ const char* testFunction, bool twoPaths, SkMemoryWStream& outFile) {
+ outFile.writeText("<div id=\"");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText("\">\n");
+ if (pathPrefix) {
+ outFile.writeText(pathPrefix);
+ }
+ outFile.writeText(pathStr);
+ outFile.writeText("</div>\n\n");
+
+ outFile.writeText(marker);
+ outFile.writeText(" ");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText(",\n\n\n");
+
+ outFile.writeText("static void ");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText("() {\n SkPath path");
+ if (twoPaths) {
+ outFile.writeText(", pathB");
+ }
+ outFile.writeText(";\n");
+ if (pathPrefix) {
+ outFile.writeText(pathPrefix);
+ }
+ outFile.writeText(pathStr);
+ outFile.writeText(" ");
+ outFile.writeText(testFunction);
+ outFile.writeText("\n}\n\n");
+ outFile.writeText("static void (*firstTest)() = ");
+ writeTestName(nameSuffix, outFile);
+ 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(");
+ writeTestName(nameSuffix, outFile);
+ outFile.writeText("),\n");
+ outFile.flush();
+}
+
+bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
+ const char* pathStr) {
SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWinding_FillType;
path.setFillType(fillType);
if (gShowPath) {
@@ -359,9 +413,8 @@ bool testSimplify(SkPath& path, bool useXor, SkPath& out, State4& state, const c
if (!gComparePaths) {
return true;
}
- int result = comparePaths(state.reporter, path, out, state.bitmap);
+ int result = comparePaths(state.fReporter, path, out, *state.fBitmap);
if (result && gPathStrAssert) {
- SkDebugf("addTest %s\n", state.filename);
char temp[8192];
sk_bzero(temp, sizeof(temp));
SkMemoryWStream stream(temp, sizeof(temp));
@@ -372,10 +425,11 @@ bool testSimplify(SkPath& path, bool useXor, SkPath& out, State4& state, const c
nameSuffix = "x";
}
const char testFunction[] = "testSimplifyx(path);";
- outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, stream);
+ outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, stream);
SkDebugf(temp);
- REPORTER_ASSERT(state.reporter, 0);
+ REPORTER_ASSERT(state.fReporter, 0);
}
+ state.fReporter->bumpTestCount();
return result == 0;
}
@@ -387,6 +441,7 @@ bool testSimplify(skiatest::Reporter* reporter, const SkPath& path) {
if (result && gPathStrAssert) {
REPORTER_ASSERT(reporter, 0);
}
+ reporter->bumpTestCount();
return result == 0;
}
@@ -428,124 +483,22 @@ bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
if (result && gPathStrAssert) {
REPORTER_ASSERT(reporter, 0);
}
+ reporter->bumpTestCount();
return result == 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;
-
-#if HARD_CODE_PTHREAD
-pthread_mutex_t State4::addQueue = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t State4::checkQueue = PTHREAD_COND_INITIALIZER;
-#else
SK_DECLARE_STATIC_MUTEX(gQueueMutex);
-#endif
-State4::State4() {
- bitmap.setConfig(SkBitmap::kARGB_8888_Config, 150 * 2, 100);
- bitmap.allocPixels();
-}
-
-void createThread(State4* statePtr, ThreadFunction testFun) {
-#if HARD_CODE_PTHREAD
- SkDEBUGCODE(int threadError =) pthread_create(&statePtr->threadID, NULL, testFun,
- (void*) statePtr);
- SkASSERT(!threadError);
-#else
- statePtr->thread = new SkThread(testFun, (void*) statePtr);
- statePtr->thread->start();
-#endif
-}
-
-int dispatchTest4(ThreadFunction testFun, int a, int b, int c, int d) {
- int testsRun = 0;
- State4* statePtr;
- if (!gRunTestsInOneThread) {
-#if HARD_CODE_PTHREAD
- pthread_mutex_lock(&State4::addQueue);
-#else
- SkAutoMutexAcquire aq(&gQueueMutex);
-#endif
- 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);
-#if HARD_CODE_PTHREAD
- pthread_cond_init(&statePtr->initialized, NULL);
-#else
- // statePtr->thread contains fData which points to SkThread_PThreadData which
- // contains PThreadEvent fStarted, all of which is initialized by createThread below
-#endif
- ++threadIndex;
- createThread(statePtr, testFun);
- } else {
- while (!State4::queue) {
- if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__);
-#if HARD_CODE_PTHREAD
- pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
-#else
- // incomplete
-#endif
- }
- 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);
-#if HARD_CODE_PTHREAD
- pthread_cond_signal(&statePtr->initialized);
-#else
- // incomplete
-#endif
- }
-#if HARD_CODE_PTHREAD
- pthread_mutex_unlock(&State4::addQueue);
+int initializeTests(const char* test) {
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = 4;
+ gDebugMaxWindValue = 4;
#endif
- } else {
- statePtr = &threadState[0];
- testsRun += statePtr->testsRun;
- statePtr->testsRun = 0;
- statePtr->a = a;
- statePtr->b = b;
- statePtr->c = c;
- statePtr->d = d;
- statePtr->done = false;
- statePtr->index = threadIndex;
- statePtr->last = false;
- (*testFun)(statePtr);
- }
- return testsRun;
-}
-
-void initializeTests(skiatest::Reporter* reporter, const char* test, size_t testNameSize) {
testName = test;
+ size_t testNameSize = strlen(test);
if (!gRunTestsInOneThread) {
int threads = -1;
#ifdef SK_BUILD_FOR_MAC
@@ -555,7 +508,7 @@ void initializeTests(skiatest::Reporter* reporter, const char* test, size_t test
if (threads > 0) {
maxThreads = threads;
} else {
- maxThreads = 8;
+ maxThreads = 16;
}
}
SkFILEStream inFile("../../experimental/Intersection/op.htm");
@@ -572,218 +525,27 @@ void initializeTests(skiatest::Reporter* reporter, const char* test, size_t test
testNumber = atoi(numLoc) + 1;
}
}
- const char* filename = "debugXX.txt";
- for (int index = 0; index < maxThreads; ++index) {
- State4* statePtr = &threadState[index];
- statePtr->reporter = reporter;
- strcpy(statePtr->filename, filename);
- size_t len = strlen(filename);
- SkASSERT(statePtr->filename[len - 6] == 'X');
- SkASSERT(statePtr->filename[len - 5] == 'X');
- statePtr->filename[len - 6] = '0' + index / 10;
- statePtr->filename[len - 5] = '0' + index % 10;
- }
- threadIndex = 0;
+ return maxThreads;
}
-void outputProgress(const State4& state, const char* pathStr, SkPath::FillType pathFillType) {
- if (gRunTestsInOneThread && gShowOutputProgress) {
- if (pathFillType == SkPath::kEvenOdd_FillType) {
- SkDebugf(" path.setFillType(SkPath::kEvenOdd_FillType);\n", pathStr);
- }
- SkDebugf("%s\n", pathStr);
- }
- const char testFunction[] = "testSimplifyx(path);";
+void outputProgress(char* ramStr, const char* pathStr, SkPath::FillType pathFillType) {
+ const char testFunction[] = "testSimplify(path);";
const char* pathPrefix = NULL;
const char* nameSuffix = NULL;
if (pathFillType == SkPath::kEvenOdd_FillType) {
pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n";
nameSuffix = "x";
}
- if (gUsePhysicalFiles) {
- SkFILEWStream outFile(state.filename);
- if (!outFile.isValid()) {
- SkASSERT(0);
- return;
- }
- outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, outFile);
- return;
- }
- state.ramStream.reset();
- outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, state.ramStream);
+ SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE);
+ outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, rRamStream);
}
-void outputProgress(const State4& state, const char* pathStr, SkPathOp op) {
- SkString testFunc("testPathOp(path, pathB, ");
- testFunc += opStrs[op];
- testFunc += ");";
- const char* testFunction = testFunc.c_str();
- if (gRunTestsInOneThread && gShowOutputProgress) {
- SkDebugf("%s\n", pathStr);
- SkDebugf(" %s\n", testFunction);
- }
+void outputProgress(char* ramStr, const char* pathStr, SkPathOp op) {
+ const char testFunction[] = "testOp(path);";
+ SkASSERT(op < sizeof(opSuffixes) / sizeof(opSuffixes[0]));
const char* nameSuffix = opSuffixes[op];
- if (gUsePhysicalFiles) {
- SkFILEWStream outFile(state.filename);
- if (!outFile.isValid()) {
- SkASSERT(0);
- return;
- }
- outputToStream(state, pathStr, NULL, nameSuffix, testFunction, outFile);
- return;
- }
- state.ramStream.reset();
- outputToStream(state, pathStr, NULL, nameSuffix, testFunction, state.ramStream);
-}
-
-static void writeTestName(const char* nameSuffix, SkWStream& outFile) {
- outFile.writeText(testName);
- outFile.writeDecAsText(testNumber);
- if (nameSuffix) {
- outFile.writeText(nameSuffix);
- }
-}
-
-void outputToStream(const State4& state, const char* pathStr, const char* pathPrefix,
- const char* nameSuffix,
- const char* testFunction, SkWStream& outFile) {
- outFile.writeText("<div id=\"");
- writeTestName(nameSuffix, outFile);
- outFile.writeText("\">\n");
- if (pathPrefix) {
- outFile.writeText(pathPrefix);
- }
- outFile.writeText(pathStr);
- outFile.writeText("</div>\n\n");
-
- outFile.writeText(marker);
- outFile.writeText(" ");
- writeTestName(nameSuffix, outFile);
- outFile.writeText(",\n\n\n");
-
- outFile.writeText("static void ");
- writeTestName(nameSuffix, outFile);
- outFile.writeText("() {\n SkPath path");
- if (!pathPrefix) {
- outFile.writeText(", pathB");
- }
- outFile.writeText(";\n");
- if (pathPrefix) {
- outFile.writeText(pathPrefix);
- }
- outFile.writeText(pathStr);
- outFile.writeText(" ");
- outFile.writeText(testFunction);
- outFile.writeText("\n}\n\n");
- outFile.writeText("static void (*firstTest)() = ");
- writeTestName(nameSuffix, outFile);
- 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(");
- writeTestName(nameSuffix, outFile);
- outFile.writeText("),\n");
- outFile.flush();
-}
-
-bool runNextTestSet(State4& state) {
- if (gRunTestsInOneThread) {
- return false;
- }
-#if HARD_CODE_PTHREAD
- pthread_mutex_lock(&State4::addQueue);
-#else
- SkAutoMutexAcquire aq(&gQueueMutex);
-#endif
- state.done = true;
- State4::queue = &state;
- if (debugThreads) SkDebugf("%s %d checkQueue done=%d last=%d\n", __FUNCTION__, state.index,
- state.done, state.last);
-#if HARD_CODE_PTHREAD
- pthread_cond_signal(&State4::checkQueue);
-#else
- // incomplete
-#endif
- while (state.done && !state.last) {
- if (debugThreads) SkDebugf("%s %d done=%d last=%d\n", __FUNCTION__, state.index, state.done, state.last);
-#if HARD_CODE_PTHREAD
- pthread_cond_wait(&state.initialized, &State4::addQueue);
-#else
- // incomplete
-#endif
- }
-#if HARD_CODE_PTHREAD
- pthread_mutex_unlock(&State4::addQueue);
-#endif
- return !state.last;
-}
-
-int waitForCompletion() {
- int testsRun = 0;
- if (!gRunTestsInOneThread) {
-#if HARD_CODE_PTHREAD
- pthread_mutex_lock(&State4::addQueue);
-#else
- SkAutoMutexAcquire aq(gQueueMutex);
-#endif
- int runningThreads = threadIndex;
- int index;
- while (runningThreads > 0) {
- while (!State4::queue) {
- if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__);
-#if HARD_CODE_PTHREAD
- pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
-#else
- // ioncomplete
-#endif
- }
- while (State4::queue) {
- --runningThreads;
-#if DEBUG_SHOW_TEST_PROGRESS
- SkDebugf("•");
-#endif
- State4::queue->last = true;
- State4* next = NULL;
- 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);
-#if HARD_CODE_PTHREAD
- pthread_cond_signal(&State4::queue->initialized);
-#else
- // incomplete
-#endif
- State4::queue = next;
- }
- }
-#if HARD_CODE_PTHREAD
- pthread_mutex_unlock(&State4::addQueue);
-#endif
- for (index = 0; index < maxThreads; ++index) {
-#if HARD_CODE_PTHREAD
- pthread_join(threadState[index].threadID, NULL);
-#else
- threadState[index].thread->join();
- delete threadState[index].thread;
-#endif
- testsRun += threadState[index].testsRun;
- }
-#if DEBUG_SHOW_TEST_PROGRESS
- SkDebugf("\n");
-#endif
- }
-#ifdef SK_DEBUG
- gDebugMaxWindSum = SK_MaxS32;
- gDebugMaxWindValue = SK_MaxS32;
-#endif
- return testsRun;
+ SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE);
+ outputToStream(pathStr, NULL, nameSuffix, testFunction, true, rRamStream);
}
void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count,
diff --git a/tests/PathOpsExtendedTest.h b/tests/PathOpsExtendedTest.h
index 59fb92d5b6..5267409c6d 100644
--- a/tests/PathOpsExtendedTest.h
+++ b/tests/PathOpsExtendedTest.h
@@ -7,45 +7,21 @@
#ifndef PathOpsExtendedTest_DEFINED
#define PathOpsExtendedTest_DEFINED
-#include "Test.h"
-#include "SkPathOpsTypes.h"
#include "SkBitmap.h"
#include "SkPath.h"
+#include "SkPathOpsTypes.h"
#include "SkStream.h"
-
-#ifdef SK_BUILD_FOR_WIN
-#define HARD_CODE_PTHREAD 0
-#else
-#define HARD_CODE_PTHREAD 1
-#endif
-
-#if HARD_CODE_PTHREAD
-#include <pthread.h>
-#else
#include "SkThread.h"
-#include "../../src/utils/SkThreadUtils.h"
-#endif
-
-#if HARD_CODE_PTHREAD
-typedef void* (*ThreadFunction)(void*);
-#define THREAD_TYPE void*
-#define THREAD_RETURN return NULL;
-#else
-typedef void (*ThreadFunction)(void*);
-#define THREAD_TYPE void
-#define THREAD_RETURN
-#endif
+#include "SkThreadUtils.h"
+#include "Test.h"
-struct State4;
+struct PathOpsThreadState;
struct TestDesc {
void (*fun)(skiatest::Reporter*);
const char* str;
};
-extern bool gShowTestProgress;
-extern bool gAllowExtendedTest;
-
//extern int comparePaths(const SkPath& one, const SkPath& two);
extern int comparePaths(const SkPath& one, const SkPath& two, SkBitmap& bitmap);
extern bool drawAsciiPaths(const SkPath& one, const SkPath& two, bool drawPaths);
@@ -55,45 +31,13 @@ extern void showPath(const SkPath& path);
extern void showPathData(const SkPath& path);
extern bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
const SkPathOp );
-extern bool testSimplify(SkPath& path, bool useXor, SkPath& out,
- State4& state, const char* pathStr);
+extern bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& state,
+ const char* pathStr);
extern bool testSimplify(skiatest::Reporter* reporter, const SkPath& path);
-struct State4 {
- State4();
-#if HARD_CODE_PTHREAD
- static pthread_mutex_t addQueue;
- static pthread_cond_t checkQueue;
- pthread_cond_t initialized;
- pthread_t threadID;
-#else
- SkThread* thread;
-#endif
- static State4* queue;
- int index;
- bool done;
- bool last;
- int a;
- int b;
- int c;
- int d; // sometimes 1 if abc_is_a_triangle
- int testsRun;
- char filename[256];
- skiatest::Reporter* reporter;
- SkBitmap bitmap;
- mutable SkDynamicMemoryWStream ramStream;
-};
-
-void createThread(State4* statePtr, void* (*test)(void* ));
-int dispatchTest4(ThreadFunction testFun, int a, int b, int c, int d);
-void initializeTests(skiatest::Reporter* reporter, const char* testName, size_t testNameSize);
-void outputProgress(const State4& state, const char* pathStr, SkPath::FillType );
-void outputProgress(const State4& state, const char* pathStr, SkPathOp op);
-void outputToStream(const State4& state, const char* pathStr, const char* pathPrefix,
- const char* nameSuffix,
- const char* testFunction, SkWStream& outFile);
-bool runNextTestSet(State4& state);
-int waitForCompletion();
+int initializeTests(const char* testName);
+void outputProgress(char* ramStr, const char* pathStr, SkPath::FillType );
+void outputProgress(char* ramStr, const char* pathStr, SkPathOp op);
void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count,
void (*firstTest)(skiatest::Reporter* ),
diff --git a/tests/PathOpsOpCubicThreadedTest.cpp b/tests/PathOpsOpCubicThreadedTest.cpp
index 80527f9e5e..31e8065470 100644
--- a/tests/PathOpsOpCubicThreadedTest.cpp
+++ b/tests/PathOpsOpCubicThreadedTest.cpp
@@ -5,87 +5,75 @@
* found in the LICENSE file.
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
-static THREAD_TYPE testOpCubicsMain(void* data)
+static void testOpCubicsMain(PathOpsThreadState* data)
{
SkASSERT(data);
- State4& state = *(State4*) data;
+ PathOpsThreadState& state = *data;
char pathStr[1024]; // gdb: set print elements 400
sk_bzero(pathStr, sizeof(pathStr));
- do {
- for (int a = 0 ; a < 6; ++a) {
- for (int b = a + 1 ; b < 7; ++b) {
- for (int c = 0 ; c < 6; ++c) {
- for (int d = c + 1 ; d < 7; ++d) {
- for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) {
- for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) {
- SkPath pathA, pathB;
- char* str = pathStr;
- pathA.setFillType((SkPath::FillType) e);
- str += sprintf(str, " path.setFillType(SkPath::k%s_FillType);\n",
- e == SkPath::kWinding_FillType ? "Winding" : e == SkPath::kEvenOdd_FillType
- ? "EvenOdd" : "?UNDEFINED");
- pathA.moveTo(SkIntToScalar(state.a), SkIntToScalar(state.b));
- str += sprintf(str, " path.moveTo(%d,%d);\n", state.a, state.b);
- pathA.cubicTo(SkIntToScalar(state.c), SkIntToScalar(state.d), SkIntToScalar(b),
- SkIntToScalar(a), SkIntToScalar(d), SkIntToScalar(c));
- str += sprintf(str, " path.cubicTo(%d,%d, %d,%d, %d,%d);\n", state.c, state.d,
- b, a, d, c);
- pathA.close();
- str += sprintf(str, " path.close();\n");
- pathB.setFillType((SkPath::FillType) f);
- str += sprintf(str, " pathB.setFillType(SkPath::k%s_FillType);\n",
- f == SkPath::kWinding_FillType ? "Winding" : f == SkPath::kEvenOdd_FillType
- ? "EvenOdd" : "?UNDEFINED");
- pathB.moveTo(SkIntToScalar(a), SkIntToScalar(b));
- str += sprintf(str, " pathB.moveTo(%d,%d);\n", a, b);
- pathB.cubicTo(SkIntToScalar(c), SkIntToScalar(d), SkIntToScalar(state.b),
- SkIntToScalar(state.a), SkIntToScalar(state.d), SkIntToScalar(state.c));
- str += sprintf(str, " pathB.cubicTo(%d,%d, %d,%d, %d,%d);\n", c, d,
- state.b, state.a, state.d, state.c);
- pathB.close();
- str += sprintf(str, " pathB.close();\n");
- for (int op = 0 ; op <= kXOR_PathOp; ++op) {
- outputProgress(state, pathStr, (SkPathOp) op);
- testPathOp(state.reporter, pathA, pathB, (SkPathOp) op);
- state.testsRun++;
- }
- }
- }
- }
+ for (int a = 0 ; a < 6; ++a) {
+ for (int b = a + 1 ; b < 7; ++b) {
+ for (int c = 0 ; c < 6; ++c) {
+ for (int d = c + 1 ; d < 7; ++d) {
+ for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) {
+ for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) {
+ SkPath pathA, pathB;
+ char* str = pathStr;
+ pathA.setFillType((SkPath::FillType) e);
+ str += sprintf(str, " path.setFillType(SkPath::k%s_FillType);\n",
+ e == SkPath::kWinding_FillType ? "Winding" : e == SkPath::kEvenOdd_FillType
+ ? "EvenOdd" : "?UNDEFINED");
+ pathA.moveTo(SkIntToScalar(state.fA), SkIntToScalar(state.fB));
+ str += sprintf(str, " path.moveTo(%d,%d);\n", state.fA, state.fB);
+ pathA.cubicTo(SkIntToScalar(state.fC), SkIntToScalar(state.fD), SkIntToScalar(b),
+ SkIntToScalar(a), SkIntToScalar(d), SkIntToScalar(c));
+ str += sprintf(str, " path.cubicTo(%d,%d, %d,%d, %d,%d);\n", state.fC, state.fD,
+ b, a, d, c);
+ pathA.close();
+ str += sprintf(str, " path.close();\n");
+ pathB.setFillType((SkPath::FillType) f);
+ str += sprintf(str, " pathB.setFillType(SkPath::k%s_FillType);\n",
+ f == SkPath::kWinding_FillType ? "Winding" : f == SkPath::kEvenOdd_FillType
+ ? "EvenOdd" : "?UNDEFINED");
+ pathB.moveTo(SkIntToScalar(a), SkIntToScalar(b));
+ str += sprintf(str, " pathB.moveTo(%d,%d);\n", a, b);
+ pathB.cubicTo(SkIntToScalar(c), SkIntToScalar(d), SkIntToScalar(state.fB),
+ SkIntToScalar(state.fA), SkIntToScalar(state.fD), SkIntToScalar(state.fC));
+ str += sprintf(str, " pathB.cubicTo(%d,%d, %d,%d, %d,%d);\n", c, d,
+ state.fB, state.fA, state.fD, state.fC);
+ pathB.close();
+ str += sprintf(str, " pathB.close();\n");
+ for (int op = 0 ; op <= kXOR_PathOp; ++op) {
+ outputProgress(state.fPathStr, pathStr, (SkPathOp) op);
+ testPathOp(state.fReporter, pathA, pathB, (SkPathOp) op);
+ }
+ }
}
}
}
- } while (runNextTestSet(state));
- THREAD_RETURN
+ }
+ }
}
static void TestOpCubicsThreaded(skiatest::Reporter* reporter)
{
- int testsRun = 0;
- if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
-#ifdef SK_DEBUG
- gDebugMaxWindSum = 4;
- gDebugMaxWindValue = 4;
-#endif
- const char testLineStr[] = "cubicOp";
- initializeTests(reporter, testLineStr, sizeof(testLineStr));
+ int threadCount = initializeTests("cubicOp");
+ PathOpsThreadedTestRunner testRunner(reporter, threadCount);
for (int a = 0; a < 6; ++a) { // outermost
for (int b = a + 1; b < 7; ++b) {
for (int c = 0 ; c < 6; ++c) {
for (int d = c + 1; d < 7; ++d) {
- testsRun += dispatchTest4(testOpCubicsMain, a, b, c, d);
+ *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+ (&testOpCubicsMain, a, b, c, d, &testRunner));
}
- if (gShowTestProgress) SkDebugf(".");
}
- if (!gAllowExtendedTest) goto finish;
- if (gShowTestProgress) SkDebugf("%d", b);
+ if (!reporter->allowExtendedTest()) goto finish;
}
- if (gShowTestProgress) SkDebugf("\n%d", a);
}
finish:
- testsRun += waitForCompletion();
- if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+ testRunner.render();
}
#include "TestClassDef.h"
diff --git a/tests/PathOpsOpRectThreadedTest.cpp b/tests/PathOpsOpRectThreadedTest.cpp
index 2f89805146..8f4bd7d1e0 100644
--- a/tests/PathOpsOpRectThreadedTest.cpp
+++ b/tests/PathOpsOpRectThreadedTest.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
// four rects, of four sizes
// for 3 smaller sizes, tall, wide
@@ -13,89 +14,77 @@
// not included, square, tall, wide (2 bits)
// cw or ccw (1 bit)
-static THREAD_TYPE testPathOpsRectsMain(void* data)
+static void testPathOpsRectsMain(PathOpsThreadState* data)
{
SkASSERT(data);
- State4& state = *(State4*) data;
+ PathOpsThreadState& state = *data;
char pathStr[1024]; // gdb: set print elements 400
sk_bzero(pathStr, sizeof(pathStr));
- do {
- for (int a = 0 ; a < 6; ++a) {
- for (int b = a + 1 ; b < 7; ++b) {
- for (int c = 0 ; c < 6; ++c) {
- for (int d = c + 1 ; d < 7; ++d) {
- for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) {
- for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) {
- SkPath pathA, pathB;
- char* str = pathStr;
- pathA.setFillType((SkPath::FillType) e);
- str += sprintf(str, " path.setFillType(SkPath::k%s_FillType);\n",
- e == SkPath::kWinding_FillType ? "Winding" : e == SkPath::kEvenOdd_FillType
- ? "EvenOdd" : "?UNDEFINED");
- pathA.addRect(SkIntToScalar(state.a), SkIntToScalar(state.a), SkIntToScalar(state.b),
- SkIntToScalar(state.b), SkPath::kCW_Direction);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " SkPath::kCW_Direction);\n", state.a, state.a, state.b, state.b);
- pathA.addRect(SkIntToScalar(state.c), SkIntToScalar(state.c), SkIntToScalar(state.d),
- SkIntToScalar(state.d), SkPath::kCW_Direction);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " SkPath::kCW_Direction);\n", state.c, state.c, state.d, state.d);
- pathA.close();
- pathB.setFillType((SkPath::FillType) f);
- str += sprintf(str, " pathB.setFillType(SkPath::k%s_FillType);\n",
- f == SkPath::kWinding_FillType ? "Winding" : f == SkPath::kEvenOdd_FillType
- ? "EvenOdd" : "?UNDEFINED");
- pathB.addRect(SkIntToScalar(a), SkIntToScalar(a), SkIntToScalar(b),
- SkIntToScalar(b), SkPath::kCW_Direction);
- str += sprintf(str, " pathB.addRect(%d, %d, %d, %d,"
- " SkPath::kCW_Direction);\n", a, a, b, b);
- pathB.addRect(SkIntToScalar(c), SkIntToScalar(c), SkIntToScalar(d),
- SkIntToScalar(d), SkPath::kCW_Direction);
- str += sprintf(str, " pathB.addRect(%d, %d, %d, %d,"
- " SkPath::kCW_Direction);\n", c, c, d, d);
- pathB.close();
- for (int op = 0 ; op <= kXOR_PathOp; ++op) {
- outputProgress(state, pathStr, (SkPathOp) op);
- testPathOp(state.reporter, pathA, pathB, (SkPathOp) op);
- state.testsRun++;
- }
- }
- }
- }
+ for (int a = 0 ; a < 6; ++a) {
+ for (int b = a + 1 ; b < 7; ++b) {
+ for (int c = 0 ; c < 6; ++c) {
+ for (int d = c + 1 ; d < 7; ++d) {
+ for (int e = SkPath::kWinding_FillType ; e <= SkPath::kEvenOdd_FillType; ++e) {
+ for (int f = SkPath::kWinding_FillType ; f <= SkPath::kEvenOdd_FillType; ++f) {
+ SkPath pathA, pathB;
+ char* str = pathStr;
+ pathA.setFillType((SkPath::FillType) e);
+ str += sprintf(str, " path.setFillType(SkPath::k%s_FillType);\n",
+ e == SkPath::kWinding_FillType ? "Winding" : e == SkPath::kEvenOdd_FillType
+ ? "EvenOdd" : "?UNDEFINED");
+ pathA.addRect(SkIntToScalar(state.fA), SkIntToScalar(state.fA), SkIntToScalar(state.fB),
+ SkIntToScalar(state.fB), SkPath::kCW_Direction);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kCW_Direction);\n", state.fA, state.fA, state.fB, state.fB);
+ pathA.addRect(SkIntToScalar(state.fC), SkIntToScalar(state.fC), SkIntToScalar(state.fD),
+ SkIntToScalar(state.fD), SkPath::kCW_Direction);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kCW_Direction);\n", state.fC, state.fC, state.fD, state.fD);
+ pathA.close();
+ pathB.setFillType((SkPath::FillType) f);
+ str += sprintf(str, " pathB.setFillType(SkPath::k%s_FillType);\n",
+ f == SkPath::kWinding_FillType ? "Winding" : f == SkPath::kEvenOdd_FillType
+ ? "EvenOdd" : "?UNDEFINED");
+ pathB.addRect(SkIntToScalar(a), SkIntToScalar(a), SkIntToScalar(b),
+ SkIntToScalar(b), SkPath::kCW_Direction);
+ str += sprintf(str, " pathB.addRect(%d, %d, %d, %d,"
+ " SkPath::kCW_Direction);\n", a, a, b, b);
+ pathB.addRect(SkIntToScalar(c), SkIntToScalar(c), SkIntToScalar(d),
+ SkIntToScalar(d), SkPath::kCW_Direction);
+ str += sprintf(str, " pathB.addRect(%d, %d, %d, %d,"
+ " SkPath::kCW_Direction);\n", c, c, d, d);
+ pathB.close();
+ for (int op = 0 ; op <= kXOR_PathOp; ++op) {
+ outputProgress(state.fPathStr, pathStr, (SkPathOp) op);
+ testPathOp(state.fReporter, pathA, pathB, (SkPathOp) op);
+ }
+ }
}
}
}
- } while (runNextTestSet(state));
- THREAD_RETURN
+ }
+ }
}
static void TestPathOpsRectsThreaded(skiatest::Reporter* reporter) {
- int testsRun = 0;
- if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
-#ifdef SK_DEBUG
- gDebugMaxWindSum = 4;
- gDebugMaxWindValue = 4;
-#endif
- const char testLineStr[] = "testOp";
- initializeTests(reporter, testLineStr, sizeof(testLineStr));
+ int threadCount = initializeTests("testOp");
+ PathOpsThreadedTestRunner testRunner(reporter, threadCount);
for (int a = 0; a < 6; ++a) { // outermost
for (int b = a + 1; b < 7; ++b) {
for (int c = 0 ; c < 6; ++c) {
for (int d = c + 1; d < 7; ++d) {
- testsRun += dispatchTest4(testPathOpsRectsMain, a, b, c, d);
+ *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+ (&testPathOpsRectsMain, a, b, c, d, &testRunner));
}
- if (gShowTestProgress) SkDebugf(".");
}
- if (!gAllowExtendedTest) goto finish;
- if (gShowTestProgress) SkDebugf("%d", b);
+ if (!reporter->allowExtendedTest()) goto finish;
}
- if (gShowTestProgress) SkDebugf("\n%d", a);
}
finish:
- testsRun += waitForCompletion();
- if (gShowTestProgress) SkDebugf("%s tests=%d total=%d\n", __FUNCTION__, testsRun);
+ testRunner.render();
}
#include "TestClassDef.h"
DEFINE_TESTCLASS("PathOpsRectsThreaded", OpRectsThreadedTestClass, \
TestPathOpsRectsThreaded)
+
diff --git a/tests/PathOpsQuadLineIntersectionThreadedTest.cpp b/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
index e3db87cfb0..c74e9619d4 100644
--- a/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
+++ b/tests/PathOpsQuadLineIntersectionThreadedTest.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
#include "SkIntersections.h"
#include "SkPathOpsLine.h"
#include "SkPathOpsQuad.h"
@@ -43,7 +44,8 @@ static void testLineIntersect(skiatest::Reporter* reporter, const SkDQuad& quad,
sk_bzero(pathStr, sizeof(pathStr));
char* str = pathStr;
str += sprintf(str, " path.moveTo(%1.9g, %1.9g);\n", quad[0].fX, quad[0].fY);
- str += sprintf(str, " path.quadTo(%1.9g, %1.9g, %1.9g, %1.9g);\n", quad[1].fX, quad[1].fY, quad[2].fX, quad[2].fY);
+ str += sprintf(str, " path.quadTo(%1.9g, %1.9g, %1.9g, %1.9g);\n", quad[1].fX,
+ quad[1].fY, quad[2].fX, quad[2].fY);
str += sprintf(str, " path.moveTo(%1.9g, %1.9g);\n", line[0].fX, line[0].fY);
str += sprintf(str, " path.lineTo(%1.9g, %1.9g);\n", line[1].fX, line[1].fY);
@@ -69,65 +71,60 @@ static void testLineIntersect(skiatest::Reporter* reporter, const SkDQuad& quad,
// verify that intersecting the vertical span and the quad returns t
// verify that a vertical span starting at quad[0] intersects at t=0
// verify that a vertical span starting at quad[2] intersects at t=1
-static THREAD_TYPE testQuadLineIntersectMain(void* data)
+static void testQuadLineIntersectMain(PathOpsThreadState* data)
{
- State4& state = *(State4*) data;
- REPORTER_ASSERT(state.reporter, data);
- 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;
- SkDQuad quad = {{{ax, ay}, {bx, by}, {cx, cy}}};
- SkReduceOrder reducer;
- int order = reducer.reduce(quad, SkReduceOrder::kFill_Style);
- if (order < 3) {
- continue; // skip degenerates
- }
- for (int tIndex = 0; tIndex <= 4; ++tIndex) {
- SkDPoint xy = quad.xyAtT(tIndex / 4.0);
- for (int h = -2; h <= 2; ++h) {
- for (int v = -2; v <= 2; ++v) {
- if (h == v && abs(h) != 1) {
- continue;
- }
- double x = xy.fX;
- double y = xy.fY;
- SkDLine line = {{{x - h, y - v}, {x, y}}};
- testLineIntersect(state.reporter, quad, line, x, y);
- SkDLine line2 = {{{x, y}, {x + h, y + v}}};
- testLineIntersect(state.reporter, quad, line2, x, y);
- SkDLine line3 = {{{x - h, y - v}, {x + h, y + v}}};
- testLineIntersect(state.reporter, quad, line3, x, y);
- state.testsRun += 3;
+ PathOpsThreadState& state = *data;
+ REPORTER_ASSERT(state.fReporter, data);
+ int ax = state.fA & 0x03;
+ int ay = state.fA >> 2;
+ int bx = state.fB & 0x03;
+ int by = state.fB >> 2;
+ int cx = state.fC & 0x03;
+ int cy = state.fC >> 2;
+ SkDQuad quad = {{{ax, ay}, {bx, by}, {cx, cy}}};
+ SkReduceOrder reducer;
+ int order = reducer.reduce(quad, SkReduceOrder::kFill_Style);
+ if (order < 3) {
+ return;
+ }
+ for (int tIndex = 0; tIndex <= 4; ++tIndex) {
+ SkDPoint xy = quad.xyAtT(tIndex / 4.0);
+ for (int h = -2; h <= 2; ++h) {
+ for (int v = -2; v <= 2; ++v) {
+ if (h == v && abs(h) != 1) {
+ continue;
}
+ double x = xy.fX;
+ double y = xy.fY;
+ SkDLine line = {{{x - h, y - v}, {x, y}}};
+ testLineIntersect(state.fReporter, quad, line, x, y);
+ state.fReporter->bumpTestCount();
+ SkDLine line2 = {{{x, y}, {x + h, y + v}}};
+ testLineIntersect(state.fReporter, quad, line2, x, y);
+ state.fReporter->bumpTestCount();
+ SkDLine line3 = {{{x - h, y - v}, {x + h, y + v}}};
+ testLineIntersect(state.fReporter, quad, line3, x, y);
+ state.fReporter->bumpTestCount();
}
}
- } while (runNextTestSet(state));
- THREAD_RETURN
+ }
}
static void TestQuadLineIntersectionThreaded(skiatest::Reporter* reporter)
{
- int testsRun = 0;
- if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
- const char testStr[] = "testQuadLineIntersect";
- initializeTests(reporter, testStr, sizeof(testStr));
+ int threadCount = initializeTests("testQuadLineIntersect");
+ PathOpsThreadedTestRunner testRunner(reporter, threadCount);
for (int a = 0; a < 16; ++a) {
for (int b = 0 ; b < 16; ++b) {
for (int c = 0 ; c < 16; ++c) {
- testsRun += dispatchTest4(testQuadLineIntersectMain, a, b, c, 0);
+ *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+ (&testQuadLineIntersectMain, a, b, c, 0, &testRunner));
}
- if (!gAllowExtendedTest) goto finish;
- if (gShowTestProgress) SkDebugf(".");
+ if (!reporter->allowExtendedTest()) goto finish;
}
- if (gShowTestProgress) SkDebugf("%d", a);
}
finish:
- testsRun += waitForCompletion();
- if (gShowTestProgress) SkDebugf("\n%s tests=%d\n", __FUNCTION__, testsRun);
+ testRunner.render();
}
#include "TestClassDef.h"
diff --git a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
index 41ddd9d7b6..ea4ed0d268 100755
--- a/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
+++ b/tests/PathOpsSimplifyDegenerateThreadedTest.cpp
@@ -5,76 +5,64 @@
* found in the LICENSE file.
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
-static THREAD_TYPE testSimplifyDegeneratesMain(void* data) {
+static void testSimplifyDegeneratesMain(PathOpsThreadState* data) {
SkASSERT(data);
- State4& state = *(State4*) data;
+ PathOpsThreadState& state = *data;
char pathStr[1024];
sk_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(SkIntToScalar(ax), SkIntToScalar(ay));
- path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
- path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
- path.close();
- path.moveTo(SkIntToScalar(dx), SkIntToScalar(dy));
- path.lineTo(SkIntToScalar(ex), SkIntToScalar(ey));
- path.lineTo(SkIntToScalar(fx), SkIntToScalar(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, SkPath::kWinding_FillType);
- testSimplify(path, false, out, state, pathStr);
- state.testsRun++;
- path.setFillType(SkPath::kEvenOdd_FillType);
- outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
- testSimplify(path, true, out, state, pathStr);
- state.testsRun++;
+ int ax = state.fA & 0x03;
+ int ay = state.fA >> 2;
+ int bx = state.fB & 0x03;
+ int by = state.fB >> 2;
+ int cx = state.fC & 0x03;
+ int cy = state.fC >> 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.fD && (ex - dx) * (fy - dy)
+ != (ey - dy) * (fx - dx)) {
+ continue;
}
+ SkPath path, out;
+ path.setFillType(SkPath::kWinding_FillType);
+ path.moveTo(SkIntToScalar(ax), SkIntToScalar(ay));
+ path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
+ path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
+ path.close();
+ path.moveTo(SkIntToScalar(dx), SkIntToScalar(dy));
+ path.lineTo(SkIntToScalar(ex), SkIntToScalar(ey));
+ path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
+ path.close();
+ 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.fPathStr, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state.fPathStr, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
}
}
- } while (runNextTestSet(state));
- THREAD_RETURN
+ }
}
static void TestSimplifyDegeneratesThreaded(skiatest::Reporter* reporter) {
- int testsRun = 0;
- if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
-#ifdef SK_DEBUG
- gDebugMaxWindSum = 2;
- gDebugMaxWindValue = 2;
-#endif
- const char testStr[] = "testDegenerates";
- initializeTests(reporter, testStr, sizeof(testStr));
+ int threadCount = initializeTests("testDegenerates");
+ PathOpsThreadedTestRunner testRunner(reporter, threadCount);
for (int a = 0; a < 16; ++a) {
int ax = a & 0x03;
int ay = a >> 2;
@@ -85,17 +73,15 @@ static void TestSimplifyDegeneratesThreaded(skiatest::Reporter* reporter) {
int cx = c & 0x03;
int cy = c >> 2;
bool abcIsATriangle = (bx - ax) * (cy - ay) != (by - ay) * (cx - ax);
- testsRun += dispatchTest4(testSimplifyDegeneratesMain,
- a, b, c, abcIsATriangle);
+ *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+ (&testSimplifyDegeneratesMain, a, b, c, abcIsATriangle,
+ &testRunner));
}
- if (!gAllowExtendedTest) goto finish;
- if (gShowTestProgress) SkDebugf(".");
+ if (!reporter->allowExtendedTest()) goto finish;
}
- if (gShowTestProgress) SkDebugf("\n%d", a);
}
finish:
- testsRun += waitForCompletion();
- if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+ testRunner.render();
}
#include "TestClassDef.h"
diff --git a/tests/PathOpsSimplifyQuadThreadedTest.cpp b/tests/PathOpsSimplifyQuadThreadedTest.cpp
index 96626a61ad..9343bc2243 100644
--- a/tests/PathOpsSimplifyQuadThreadedTest.cpp
+++ b/tests/PathOpsSimplifyQuadThreadedTest.cpp
@@ -5,98 +5,85 @@
* found in the LICENSE file.
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
-static THREAD_TYPE testSimplifyQuadsMain(void* data)
+static void testSimplifyQuadsMain(PathOpsThreadState* data)
{
SkASSERT(data);
- State4& state = *(State4*) data;
+ PathOpsThreadState& state = *data;
char pathStr[1024];
sk_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(SkIntToScalar(ax), SkIntToScalar(ay));
- path.quadTo(SkIntToScalar(bx), SkIntToScalar(by),
- SkIntToScalar(cx), SkIntToScalar(cy));
- path.lineTo(SkIntToScalar(dx), SkIntToScalar(dy));
- path.close();
- path.moveTo(SkIntToScalar(ex), SkIntToScalar(ey));
- path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
- path.quadTo(SkIntToScalar(gx), SkIntToScalar(gy),
- SkIntToScalar(hx), SkIntToScalar(hy));
- path.close();
- // 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, SkPath::kWinding_FillType);
- testSimplify(path, false, out, state, pathStr);
- state.testsRun++;
- path.setFillType(SkPath::kEvenOdd_FillType);
- outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
- testSimplify(path, true, out, state, pathStr);
- state.testsRun++;
- }
+ int ax = state.fA & 0x03;
+ int ay = state.fA >> 2;
+ int bx = state.fB & 0x03;
+ int by = state.fB >> 2;
+ int cx = state.fC & 0x03;
+ int cy = state.fC >> 2;
+ int dx = state.fD & 0x03;
+ int dy = state.fD >> 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(SkIntToScalar(ax), SkIntToScalar(ay));
+ path.quadTo(SkIntToScalar(bx), SkIntToScalar(by),
+ SkIntToScalar(cx), SkIntToScalar(cy));
+ path.lineTo(SkIntToScalar(dx), SkIntToScalar(dy));
+ path.close();
+ path.moveTo(SkIntToScalar(ex), SkIntToScalar(ey));
+ path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
+ path.quadTo(SkIntToScalar(gx), SkIntToScalar(gy),
+ SkIntToScalar(hx), SkIntToScalar(hy));
+ path.close();
+ // 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.fPathStr, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state.fPathStr, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
}
}
}
- } while (runNextTestSet(state));
- THREAD_RETURN
+ }
}
static void TestSimplifyQuadsThreaded(skiatest::Reporter* reporter)
{
- int testsRun = 0;
- if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
-#ifdef SK_DEBUG
- gDebugMaxWindSum = 4; // FIXME: 3?
- gDebugMaxWindValue = 4;
-#endif
- const char testStr[] = "testQuads";
- initializeTests(reporter, testStr, sizeof(testStr));
+ int threadCount = initializeTests("testQuads");
+ PathOpsThreadedTestRunner testRunner(reporter, threadCount);
int a = 0;
for (; 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(testSimplifyQuadsMain, a, b, c, d);
+ *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+ (&testSimplifyQuadsMain, a, b, c, d, &testRunner));
}
- if (!gAllowExtendedTest) goto finish;
- if (gShowTestProgress) SkDebugf(".");
+ if (!reporter->allowExtendedTest()) goto finish;
}
- if (gShowTestProgress) SkDebugf("%d", b);
}
- if (gShowTestProgress) SkDebugf("\n%d", a);
}
finish:
- testsRun += waitForCompletion();
- if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+ testRunner.render();
}
#include "TestClassDef.h"
diff --git a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
index ebe7e2300d..93b3fe6f1e 100755
--- a/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
+++ b/tests/PathOpsSimplifyQuadralateralsThreadedTest.cpp
@@ -5,100 +5,86 @@
* found in the LICENSE file.
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
-static THREAD_TYPE testSimplifyQuadralateralsMain(void* data)
+static void testSimplifyQuadralateralsMain(PathOpsThreadState* data)
{
SkASSERT(data);
- State4& state = *(State4*) data;
+ PathOpsThreadState& state = *data;
char pathStr[1024];
sk_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(SkIntToScalar(ax), SkIntToScalar(ay));
- path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
- path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
- path.lineTo(SkIntToScalar(dx), SkIntToScalar(dy));
- path.close();
- path.moveTo(SkIntToScalar(ex), SkIntToScalar(ey));
- path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
- path.lineTo(SkIntToScalar(gx), SkIntToScalar(gy));
- path.lineTo(SkIntToScalar(hx), SkIntToScalar(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, SkPath::kWinding_FillType);
- testSimplify(path, false, out, state, pathStr);
- state.testsRun++;
- path.setFillType(SkPath::kEvenOdd_FillType);
- outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
- testSimplify(path, true, out, state, pathStr);
- state.testsRun++;
- }
+ int ax = state.fA & 0x03;
+ int ay = state.fA >> 2;
+ int bx = state.fB & 0x03;
+ int by = state.fB >> 2;
+ int cx = state.fC & 0x03;
+ int cy = state.fC >> 2;
+ int dx = state.fD & 0x03;
+ int dy = state.fD >> 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(SkIntToScalar(ax), SkIntToScalar(ay));
+ path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
+ path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
+ path.lineTo(SkIntToScalar(dx), SkIntToScalar(dy));
+ path.close();
+ path.moveTo(SkIntToScalar(ex), SkIntToScalar(ey));
+ path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
+ path.lineTo(SkIntToScalar(gx), SkIntToScalar(gy));
+ path.lineTo(SkIntToScalar(hx), SkIntToScalar(hy));
+ path.close();
+ // 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.fPathStr, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state.fPathStr, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
}
}
}
- } while (runNextTestSet(state));
- THREAD_RETURN
+ }
}
static void TestSimplifyQuadralateralsThreaded(skiatest::Reporter* reporter)
{
- int testsRun = 0;
- if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
-#ifdef SK_DEBUG
- gDebugMaxWindSum = 4; // FIXME: 3?
- gDebugMaxWindValue = 4;
-#endif
- const char testStr[] = "testQuadralaterals";
- initializeTests(reporter, testStr, sizeof(testStr));
+ int threadCount = initializeTests("testQuadralaterals");
+ PathOpsThreadedTestRunner testRunner(reporter, threadCount);
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(testSimplifyQuadralateralsMain, a, b, c, d);
+ *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+ (&testSimplifyQuadralateralsMain, a, b, c, d, &testRunner));
}
- if (!gAllowExtendedTest) goto finish;
- if (gShowTestProgress) SkDebugf(".");
+ if (!reporter->allowExtendedTest()) goto finish;
}
- if (gShowTestProgress) SkDebugf("%d", b);
}
- if (gShowTestProgress) SkDebugf("\n%d", a);
}
finish:
- testsRun += waitForCompletion();
- if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+ testRunner.render();
}
#include "TestClassDef.h"
diff --git a/tests/PathOpsSimplifyRectThreadedTest.cpp b/tests/PathOpsSimplifyRectThreadedTest.cpp
index 13f327a06f..bd8023cd82 100644
--- a/tests/PathOpsSimplifyRectThreadedTest.cpp
+++ b/tests/PathOpsSimplifyRectThreadedTest.cpp
@@ -5,6 +5,7 @@
* found in the LICENSE file.
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
// four rects, of four sizes
// for 3 smaller sizes, tall, wide
@@ -13,194 +14,180 @@
// not included, square, tall, wide (2 bits)
// cw or ccw (1 bit)
-static THREAD_TYPE testSimplify4x4RectsMain(void* data)
+static void testSimplify4x4RectsMain(PathOpsThreadState* data)
{
SkASSERT(data);
- State4& state = *(State4*) data;
+ PathOpsThreadState& state = *data;
char pathStr[1024]; // gdb: set print elements 400
sk_bzero(pathStr, sizeof(pathStr));
- do {
- int aShape = state.a & 0x03;
- SkPath::Direction aCW = state.a >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
- int bShape = state.b & 0x03;
- SkPath::Direction bCW = state.b >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
- int cShape = state.c & 0x03;
- SkPath::Direction cCW = state.c >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
- int dShape = state.d & 0x03;
- SkPath::Direction dCW = state.d >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
- 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(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
- aCW);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " SkPath::kC%sW_Direction);\n", l, t, r, b, aCW ? "C" : "");
- } else {
- aXAlign = 5;
- aYAlign = 5;
+ int aShape = state.fA & 0x03;
+ SkPath::Direction aCW = state.fA >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+ int bShape = state.fB & 0x03;
+ SkPath::Direction bCW = state.fB >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+ int cShape = state.fC & 0x03;
+ SkPath::Direction cCW = state.fC >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+ int dShape = state.fD & 0x03;
+ SkPath::Direction dCW = state.fD >> 2 ? SkPath::kCCW_Direction : SkPath::kCW_Direction;
+ 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;
}
- 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(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
- bCW);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " SkPath::kC%sW_Direction);\n", l, t, r, b, bCW ? "C" : "");
- } else {
- bXAlign = 5;
- bYAlign = 5;
+ path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
+ aCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kC%sW_Direction);\n", l, t, r, b, aCW ? "C" : "");
+ } 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 (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(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
- cCW);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " SkPath::kC%sW_Direction);\n", l, t, r, b, cCW ? "C" : "");
- } else {
- cXAlign = 5;
- cYAlign = 5;
+ path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
+ bCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kC%sW_Direction);\n", l, t, r, b, bCW ? "C" : "");
+ } 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 (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(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
- dCW);
- str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
- " SkPath::kC%sW_Direction);\n", l, t, r, b, dCW ? "C" : "");
- } else {
- dXAlign = 5;
- dYAlign = 5;
+ path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
+ cCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kC%sW_Direction);\n", l, t, r, b, cCW ? "C" : "");
+ } 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;
}
- path.close();
- outputProgress(state, pathStr, SkPath::kWinding_FillType);
- testSimplify(path, false, out, state, pathStr);
- state.testsRun++;
- outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
- testSimplify(path, true, out, state, pathStr);
- state.testsRun++;
- }
- }
+ path.addRect(SkIntToScalar(l), SkIntToScalar(t), SkIntToScalar(r), SkIntToScalar(b),
+ dCW);
+ str += sprintf(str, " path.addRect(%d, %d, %d, %d,"
+ " SkPath::kC%sW_Direction);\n", l, t, r, b, dCW ? "C" : "");
+ } else {
+ dXAlign = 5;
+ dYAlign = 5;
+ }
+ path.close();
+ outputProgress(state.fPathStr, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ outputProgress(state.fPathStr, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
+ }
}
}
}
}
}
}
- } while (runNextTestSet(state));
- THREAD_RETURN
+ }
}
static void TestSimplifyRectsThreaded(skiatest::Reporter* reporter)
{
- int testsRun = 0;
- if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
-#ifdef SK_DEBUG
- gDebugMaxWindSum = 4;
- gDebugMaxWindValue = 4;
-#endif
- const char testLineStr[] = "testLine";
- initializeTests(reporter, testLineStr, sizeof(testLineStr));
+ int threadCount = initializeTests("testLine");
+ PathOpsThreadedTestRunner testRunner(reporter, threadCount);
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) {
- testsRun += dispatchTest4(testSimplify4x4RectsMain, a, b, c, d);
+ *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+ (&testSimplify4x4RectsMain, a, b, c, d, &testRunner));
}
- if (!gAllowExtendedTest) goto finish;
- if (gShowTestProgress) SkDebugf(".");
+ if (!reporter->allowExtendedTest()) goto finish;
}
- if (gShowTestProgress) SkDebugf("%d", b);
}
- if (gShowTestProgress) SkDebugf("\n%d", a);
}
finish:
- testsRun += waitForCompletion();
- if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+ testRunner.render();
}
#include "TestClassDef.h"
diff --git a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
index 567713ce6e..ae72a723e6 100755
--- a/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
+++ b/tests/PathOpsSimplifyTrianglesThreadedTest.cpp
@@ -5,78 +5,66 @@
* found in the LICENSE file.
*/
#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
-static THREAD_TYPE testSimplifyTrianglesMain(void* data) {
+static void testSimplifyTrianglesMain(PathOpsThreadState* data) {
SkASSERT(data);
- State4& state = *(State4*) data;
+ PathOpsThreadState& state = *data;
char pathStr[1024];
sk_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(SkIntToScalar(ax), SkIntToScalar(ay));
- path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
- path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
- path.close();
- path.moveTo(SkIntToScalar(dx), SkIntToScalar(dy));
- path.lineTo(SkIntToScalar(ex), SkIntToScalar(ey));
- path.lineTo(SkIntToScalar(fx), SkIntToScalar(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, SkPath::kWinding_FillType);
- testSimplify(path, false, out, state, pathStr);
- state.testsRun++;
- path.setFillType(SkPath::kEvenOdd_FillType);
- outputProgress(state, pathStr, SkPath::kEvenOdd_FillType);
- testSimplify(path, true, out, state, pathStr);
- state.testsRun++;
+ int ax = state.fA & 0x03;
+ int ay = state.fA >> 2;
+ int bx = state.fB & 0x03;
+ int by = state.fB >> 2;
+ int cx = state.fC & 0x03;
+ int cy = state.fC >> 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(SkIntToScalar(ax), SkIntToScalar(ay));
+ path.lineTo(SkIntToScalar(bx), SkIntToScalar(by));
+ path.lineTo(SkIntToScalar(cx), SkIntToScalar(cy));
+ path.close();
+ path.moveTo(SkIntToScalar(dx), SkIntToScalar(dy));
+ path.lineTo(SkIntToScalar(ex), SkIntToScalar(ey));
+ path.lineTo(SkIntToScalar(fx), SkIntToScalar(fy));
+ path.close();
+ 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.fPathStr, pathStr, SkPath::kWinding_FillType);
+ testSimplify(path, false, out, state, pathStr);
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ outputProgress(state.fPathStr, pathStr, SkPath::kEvenOdd_FillType);
+ testSimplify(path, true, out, state, pathStr);
}
}
- } while (runNextTestSet(state));
- THREAD_RETURN
+ }
}
static void TestSimplifyTrianglesThreaded(skiatest::Reporter* reporter) {
- int testsRun = 0;
- if (gShowTestProgress) SkDebugf("%s\n", __FUNCTION__);
-#ifdef SK_DEBUG
- gDebugMaxWindSum = 2;
- gDebugMaxWindValue = 2;
-#endif
- const char testStr[] = "testTriangles";
- initializeTests(reporter, testStr, sizeof(testStr));
+ int threadCount = initializeTests("testTriangles");
+ PathOpsThreadedTestRunner testRunner(reporter, threadCount);
for (int a = 0; a < 15; ++a) {
int ax = a & 0x03;
int ay = a >> 2;
@@ -92,16 +80,14 @@ static void TestSimplifyTrianglesThreaded(skiatest::Reporter* reporter) {
if ((bx - ax) * (cy - ay) == (by - ay) * (cx - ax)) {
continue;
}
- testsRun += dispatchTest4(testSimplifyTrianglesMain, a, b, c, 0);
+ *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable,
+ (&testSimplifyTrianglesMain, a, b, c, 0, &testRunner));
}
- if (!gAllowExtendedTest) goto finish;
- if (gShowTestProgress) SkDebugf(".");
+ if (!reporter->allowExtendedTest()) goto finish;
}
- if (gShowTestProgress) SkDebugf("\n%d", a);
}
finish:
- testsRun += waitForCompletion();
- if (gShowTestProgress) SkDebugf("%s tests=%d\n", __FUNCTION__, testsRun);
+ testRunner.render();
}
#include "TestClassDef.h"
diff --git a/tests/PathOpsThreadedCommon.cpp b/tests/PathOpsThreadedCommon.cpp
new file mode 100644
index 0000000000..44e86ab50d
--- /dev/null
+++ b/tests/PathOpsThreadedCommon.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "PathOpsExtendedTest.h"
+#include "PathOpsThreadedCommon.h"
+
+PathOpsThreadedTestRunner::~PathOpsThreadedTestRunner() {
+ for (int index = 0; index < fRunnables.count(); index++) {
+ SkDELETE(fRunnables[index]);
+ }
+}
+
+void PathOpsThreadedTestRunner::render() {
+ fCountdown.reset(fRunnables.count());
+ for (int index = 0; index < fRunnables.count(); ++ index) {
+ fThreadPool.add(fRunnables[index]);
+ }
+ fCountdown.wait();
+#ifdef SK_DEBUG
+ gDebugMaxWindSum = SK_MaxS32;
+ gDebugMaxWindValue = SK_MaxS32;
+#endif
+}
+
+
diff --git a/tests/PathOpsThreadedCommon.h b/tests/PathOpsThreadedCommon.h
new file mode 100644
index 0000000000..7f57a7bbd5
--- /dev/null
+++ b/tests/PathOpsThreadedCommon.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#ifndef PathOpsThreadedCommon_DEFINED
+#define PathOpsThreadedCommon_DEFINED
+
+#include "SkCountdown.h"
+#include "SkRunnable.h"
+#include "SkTDArray.h"
+#include "SkThreadPool.h"
+
+#define PATH_STR_SIZE 512
+
+class PathOpsThreadedRunnable;
+class skiatest::Reporter;
+
+struct PathOpsThreadState {
+ unsigned char fA;
+ unsigned char fB;
+ unsigned char fC;
+ unsigned char fD;
+ char* fPathStr;
+ skiatest::Reporter* fReporter;
+ SkBitmap* fBitmap;
+};
+
+class PathOpsThreadedTestRunner {
+public:
+ PathOpsThreadedTestRunner(skiatest::Reporter* reporter, int threadCount)
+ : fNumThreads(threadCount)
+ , fThreadPool(threadCount)
+ , fCountdown(threadCount)
+ , fReporter(reporter) {
+ }
+
+ ~PathOpsThreadedTestRunner();
+
+ void render();
+
+public:
+ int fNumThreads;
+ SkTDArray<PathOpsThreadedRunnable*> fRunnables;
+ SkThreadPool fThreadPool;
+ SkCountdown fCountdown;
+ skiatest::Reporter* fReporter;
+};
+
+class PathOpsThreadedRunnable : public SkRunnable {
+public:
+ PathOpsThreadedRunnable(void (*testFun)(PathOpsThreadState*), int a, int b, int c, int d,
+ PathOpsThreadedTestRunner* runner) {
+ fState.fA = a;
+ fState.fB = b;
+ fState.fC = c;
+ fState.fD = d;
+ fState.fReporter = runner->fReporter;
+ fTestFun = testFun;
+ fDone = &runner->fCountdown;
+ }
+
+ virtual void run() SK_OVERRIDE {
+ SkBitmap bitmap;
+ fState.fBitmap = &bitmap;
+ char pathStr[PATH_STR_SIZE];
+ fState.fPathStr = pathStr;
+ (*fTestFun)(&fState);
+ fDone->run();
+ }
+
+private:
+ PathOpsThreadState fState;
+ void (*fTestFun)(PathOpsThreadState*);
+ SkRunnable* fDone;
+};
+
+#endif