Index: tests/PathOpsExtendedTest.cpp |
=================================================================== |
--- tests/PathOpsExtendedTest.cpp (revision 8570) |
+++ tests/PathOpsExtendedTest.cpp (working copy) |
@@ -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 @@ |
"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 @@ |
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 @@ |
SkPath scaled; |
SkMatrix inverse; |
bool success = scale.invert(&inverse); |
- if (!success) { |
+ if (!success) { |
SkASSERT(0); |
} |
path.transform(inverse, &scaled); |
@@ -330,7 +328,7 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
if (result && gPathStrAssert) { |
REPORTER_ASSERT(reporter, 0); |
} |
+ reporter->bumpTestCount(); |
return result == 0; |
} |
@@ -428,124 +483,22 @@ |
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(); |
+int initializeTests(const char* test) { |
+#ifdef SK_DEBUG |
+ gDebugMaxWindSum = 4; |
+ gDebugMaxWindValue = 4; |
#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); |
-#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 @@ |
if (threads > 0) { |
maxThreads = threads; |
} else { |
- maxThreads = 8; |
+ maxThreads = 16; |
} |
} |
SkFILEStream inFile("../../experimental/Intersection/op.htm"); |
@@ -572,220 +525,29 @@ |
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); |
+ SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE); |
+ outputToStream(pathStr, NULL, nameSuffix, testFunction, true, rRamStream); |
} |
-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; |
-} |
- |
void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count, |
void (*firstTest)(skiatest::Reporter* ), |
void (*stopTest)(skiatest::Reporter* ), bool reverse) { |