aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests/PathOpsExtendedTest.cpp
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 /tests/PathOpsExtendedTest.cpp
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
Diffstat (limited to 'tests/PathOpsExtendedTest.cpp')
-rw-r--r--tests/PathOpsExtendedTest.cpp416
1 files changed, 89 insertions, 327 deletions
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,