Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: tests/PathOpsExtendedTest.cpp

Issue 14072002: Make parallel unit testing work on windows (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tests/PathOpsExtendedTest.h ('k') | tests/PathOpsOpCubicThreadedTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "PathOpsExtendedTest.h" 8 #include "PathOpsExtendedTest.h"
9 #include "PathOpsThreadedCommon.h"
9 #include "SkBitmap.h" 10 #include "SkBitmap.h"
10 #include "SkCanvas.h" 11 #include "SkCanvas.h"
11 #include "SkMatrix.h" 12 #include "SkMatrix.h"
12 #include "SkPaint.h" 13 #include "SkPaint.h"
13 #include "SkStream.h" 14 #include "SkStream.h"
14 15
15 #ifdef SK_BUILD_FOR_MAC 16 #ifdef SK_BUILD_FOR_MAC
16 #include <sys/sysctl.h> 17 #include <sys/sysctl.h>
17 #endif 18 #endif
18 19
19 bool gShowTestProgress = false;
20 bool gAllowExtendedTest = false;
21
22 static const char marker[] = 20 static const char marker[] =
23 "</div>\n" 21 "</div>\n"
24 "\n" 22 "\n"
25 "<script type=\"text/javascript\">\n" 23 "<script type=\"text/javascript\">\n"
26 "\n" 24 "\n"
27 "var testDivs = [\n"; 25 "var testDivs = [\n";
28 26
29 static const char* opStrs[] = { 27 static const char* opStrs[] = {
30 "kDifference_PathOp", 28 "kDifference_PathOp",
31 "kIntersect_PathOp", 29 "kIntersect_PathOp",
32 "kUnion_PathOp", 30 "kUnion_PathOp",
33 "kXor_PathOp", 31 "kXor_PathOp",
34 }; 32 };
35 33
36 static const char* opSuffixes[] = { 34 static const char* opSuffixes[] = {
37 "d", 35 "d",
38 "i", 36 "i",
39 "u", 37 "u",
40 "x", 38 "o",
41 }; 39 };
42 40
43 static bool gShowPath = false; 41 static bool gShowPath = false;
44 static bool gComparePaths = true; 42 static bool gComparePaths = true;
45 static bool gShowOutputProgress = false;
46 static bool gComparePathsAssert = true; 43 static bool gComparePathsAssert = true;
47 static bool gPathStrAssert = true; 44 static bool gPathStrAssert = true;
48 static bool gUsePhysicalFiles = false;
49 45
50 #if FORCE_RELEASE && !defined SK_BUILD_FOR_WIN 46 #if FORCE_RELEASE
51 static bool gRunTestsInOneThread = false; 47 static bool gRunTestsInOneThread = false;
52 #else 48 #else
53 static bool gRunTestsInOneThread = true; 49 static bool gRunTestsInOneThread = true;
54 #endif 50 #endif
55 51
56 static void showPathContour(SkPath::Iter& iter) { 52 static void showPathContour(SkPath::Iter& iter) {
57 uint8_t verb; 53 uint8_t verb;
58 SkPoint pts[4]; 54 SkPoint pts[4];
59 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 55 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
60 switch (verb) { 56 switch (verb) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 109
114 void showPathData(const SkPath& path) { 110 void showPathData(const SkPath& path) {
115 SkPath::Iter iter(path, true); 111 SkPath::Iter iter(path, true);
116 uint8_t verb; 112 uint8_t verb;
117 SkPoint pts[4]; 113 SkPoint pts[4];
118 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { 114 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
119 switch (verb) { 115 switch (verb) {
120 case SkPath::kMove_Verb: 116 case SkPath::kMove_Verb:
121 continue; 117 continue;
122 case SkPath::kLine_Verb: 118 case SkPath::kLine_Verb:
123 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0]. fY, pts[1].fX, pts[1].fY); 119 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0]. fY,
120 pts[1].fX, pts[1].fY);
124 break; 121 break;
125 case SkPath::kQuad_Verb: 122 case SkPath::kQuad_Verb:
126 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", 123 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n",
127 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2 ].fY); 124 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p ts[2].fY);
128 break; 125 break;
129 case SkPath::kCubic_Verb: 126 case SkPath::kCubic_Verb:
130 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,% 1.9g}},\n", 127 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,% 1.9g}},\n",
131 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, pts[2 ].fY, pts[3].fX, pts[3].fY); 128 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p ts[2].fY,
129 pts[3].fX, pts[3].fY);
132 break; 130 break;
133 case SkPath::kClose_Verb: 131 case SkPath::kClose_Verb:
134 break; 132 break;
135 default: 133 default:
136 SkDEBUGFAIL("bad verb"); 134 SkDEBUGFAIL("bad verb");
137 return; 135 return;
138 } 136 }
139 } 137 }
140 } 138 }
141 139
(...skipping 13 matching lines...) Expand all
155 break; 153 break;
156 default: 154 default:
157 SkASSERT(0); 155 SkASSERT(0);
158 } 156 }
159 } 157 }
160 158
161 static void showPath(const SkPath& path, const char* str, const SkMatrix& scale) { 159 static void showPath(const SkPath& path, const char* str, const SkMatrix& scale) {
162 SkPath scaled; 160 SkPath scaled;
163 SkMatrix inverse; 161 SkMatrix inverse;
164 bool success = scale.invert(&inverse); 162 bool success = scale.invert(&inverse);
165 if (!success) { 163 if (!success) {
166 SkASSERT(0); 164 SkASSERT(0);
167 } 165 }
168 path.transform(inverse, &scaled); 166 path.transform(inverse, &scaled);
169 showPath(scaled, str); 167 showPath(scaled, str);
170 } 168 }
171 169
172 const int bitWidth = 64; 170 const int bitWidth = 64;
173 const int bitHeight = 64; 171 const int bitHeight = 64;
174 172
175 static void scaleMatrix(const SkPath& one, const SkPath& two, SkMatrix& scale) { 173 static void scaleMatrix(const SkPath& one, const SkPath& two, SkMatrix& scale) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 SkDebugf("op: %s\n", opStrs[shapeOp]); 321 SkDebugf("op: %s\n", opStrs[shapeOp]);
324 showPath(b, "subtrahend:"); 322 showPath(b, "subtrahend:");
325 // the region often isn't very helpful since it approximates curves with a l ot of line-tos 323 // the region often isn't very helpful since it approximates curves with a l ot of line-tos
326 if (0) showPath(scaledOne, "region:", scale); 324 if (0) showPath(scaledOne, "region:", scale);
327 showPath(two, "op result:"); 325 showPath(two, "op result:");
328 drawAsciiPaths(scaledOne, scaledTwo, true); 326 drawAsciiPaths(scaledOne, scaledTwo, true);
329 } 327 }
330 328
331 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S kPath& scaledOne, 329 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S kPath& scaledOne,
332 const SkPath& two, const SkPath& scaledTwo, SkBitmap& bi tmap, 330 const SkPath& two, const SkPath& scaledTwo, SkBitmap& bi tmap,
333 const SkPath& a, const SkPath& b, const SkPathOp shapeOp , 331 const SkPath& a, const SkPath& b, const SkPathOp shapeOp ,
334 const SkMatrix& scale) { 332 const SkMatrix& scale) {
335 int errors2x2; 333 int errors2x2;
336 int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); 334 int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2);
337 if (errors2x2 == 0) { 335 if (errors2x2 == 0) {
338 return 0; 336 return 0;
339 } 337 }
340 const int MAX_ERRORS = 8; 338 const int MAX_ERRORS = 8;
341 if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { 339 if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) {
342 showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale); 340 showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
343 } 341 }
344 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { 342 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) {
345 SkDebugf("%s errors=%d\n", __FUNCTION__, errors); 343 SkDebugf("%s errors=%d\n", __FUNCTION__, errors);
346 showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale); 344 showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale);
347 REPORTER_ASSERT(reporter, 0); 345 REPORTER_ASSERT(reporter, 0);
348 } 346 }
349 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; 347 return errors2x2 > MAX_ERRORS ? errors2x2 : 0;
350 } 348 }
351 349
352 bool testSimplify(SkPath& path, bool useXor, SkPath& out, State4& state, const c har* pathStr) { 350 static int testNumber;
351 static const char* testName;
352
353 static void writeTestName(const char* nameSuffix, SkMemoryWStream& outFile) {
354 outFile.writeText(testName);
355 outFile.writeDecAsText(testNumber);
356 if (nameSuffix) {
357 outFile.writeText(nameSuffix);
358 }
359 }
360
361 static void outputToStream(const char* pathStr, const char* pathPrefix, const ch ar* nameSuffix,
362 const char* testFunction, bool twoPaths, SkMemoryWStream& outFile) {
363 outFile.writeText("<div id=\"");
364 writeTestName(nameSuffix, outFile);
365 outFile.writeText("\">\n");
366 if (pathPrefix) {
367 outFile.writeText(pathPrefix);
368 }
369 outFile.writeText(pathStr);
370 outFile.writeText("</div>\n\n");
371
372 outFile.writeText(marker);
373 outFile.writeText(" ");
374 writeTestName(nameSuffix, outFile);
375 outFile.writeText(",\n\n\n");
376
377 outFile.writeText("static void ");
378 writeTestName(nameSuffix, outFile);
379 outFile.writeText("() {\n SkPath path");
380 if (twoPaths) {
381 outFile.writeText(", pathB");
382 }
383 outFile.writeText(";\n");
384 if (pathPrefix) {
385 outFile.writeText(pathPrefix);
386 }
387 outFile.writeText(pathStr);
388 outFile.writeText(" ");
389 outFile.writeText(testFunction);
390 outFile.writeText("\n}\n\n");
391 outFile.writeText("static void (*firstTest)() = ");
392 writeTestName(nameSuffix, outFile);
393 outFile.writeText(";\n\n");
394
395 outFile.writeText("static struct {\n");
396 outFile.writeText(" void (*fun)();\n");
397 outFile.writeText(" const char* str;\n");
398 outFile.writeText("} tests[] = {\n");
399 outFile.writeText(" TEST(");
400 writeTestName(nameSuffix, outFile);
401 outFile.writeText("),\n");
402 outFile.flush();
403 }
404
405 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st ate,
406 const char* pathStr) {
353 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi nding_FillType; 407 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi nding_FillType;
354 path.setFillType(fillType); 408 path.setFillType(fillType);
355 if (gShowPath) { 409 if (gShowPath) {
356 showPath(path); 410 showPath(path);
357 } 411 }
358 Simplify(path, &out); 412 Simplify(path, &out);
359 if (!gComparePaths) { 413 if (!gComparePaths) {
360 return true; 414 return true;
361 } 415 }
362 int result = comparePaths(state.reporter, path, out, state.bitmap); 416 int result = comparePaths(state.fReporter, path, out, *state.fBitmap);
363 if (result && gPathStrAssert) { 417 if (result && gPathStrAssert) {
364 SkDebugf("addTest %s\n", state.filename);
365 char temp[8192]; 418 char temp[8192];
366 sk_bzero(temp, sizeof(temp)); 419 sk_bzero(temp, sizeof(temp));
367 SkMemoryWStream stream(temp, sizeof(temp)); 420 SkMemoryWStream stream(temp, sizeof(temp));
368 const char* pathPrefix = NULL; 421 const char* pathPrefix = NULL;
369 const char* nameSuffix = NULL; 422 const char* nameSuffix = NULL;
370 if (fillType == SkPath::kEvenOdd_FillType) { 423 if (fillType == SkPath::kEvenOdd_FillType) {
371 pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; 424 pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n";
372 nameSuffix = "x"; 425 nameSuffix = "x";
373 } 426 }
374 const char testFunction[] = "testSimplifyx(path);"; 427 const char testFunction[] = "testSimplifyx(path);";
375 outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, str eam); 428 outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, str eam);
376 SkDebugf(temp); 429 SkDebugf(temp);
377 REPORTER_ASSERT(state.reporter, 0); 430 REPORTER_ASSERT(state.fReporter, 0);
378 } 431 }
432 state.fReporter->bumpTestCount();
379 return result == 0; 433 return result == 0;
380 } 434 }
381 435
382 bool testSimplify(skiatest::Reporter* reporter, const SkPath& path) { 436 bool testSimplify(skiatest::Reporter* reporter, const SkPath& path) {
383 SkPath out; 437 SkPath out;
384 Simplify(path, &out); 438 Simplify(path, &out);
385 SkBitmap bitmap; 439 SkBitmap bitmap;
386 int result = comparePaths(reporter, path, out, bitmap); 440 int result = comparePaths(reporter, path, out, bitmap);
387 if (result && gPathStrAssert) { 441 if (result && gPathStrAssert) {
388 REPORTER_ASSERT(reporter, 0); 442 REPORTER_ASSERT(reporter, 0);
389 } 443 }
444 reporter->bumpTestCount();
390 return result == 0; 445 return result == 0;
391 } 446 }
392 447
393 bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, 448 bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b,
394 const SkPathOp shapeOp) { 449 const SkPathOp shapeOp) {
395 #if FORCE_RELEASE == 0 450 #if FORCE_RELEASE == 0
396 showPathData(a); 451 showPathData(a);
397 showOp(shapeOp); 452 showOp(shapeOp);
398 showPathData(b); 453 showPathData(b);
399 #endif 454 #endif
(...skipping 21 matching lines...) Expand all
421 scaledRgnOut.getBoundaryPath(&scaledPathOut); 476 scaledRgnOut.getBoundaryPath(&scaledPathOut);
422 SkBitmap bitmap; 477 SkBitmap bitmap;
423 SkPath scaledOut; 478 SkPath scaledOut;
424 scaledOut.addPath(out, scale); 479 scaledOut.addPath(out, scale);
425 scaledOut.setFillType(out.getFillType()); 480 scaledOut.setFillType(out.getFillType());
426 int result = comparePaths(reporter, pathOut, scaledPathOut, out, scaledOut, bitmap, a, b, 481 int result = comparePaths(reporter, pathOut, scaledPathOut, out, scaledOut, bitmap, a, b,
427 shapeOp, scale); 482 shapeOp, scale);
428 if (result && gPathStrAssert) { 483 if (result && gPathStrAssert) {
429 REPORTER_ASSERT(reporter, 0); 484 REPORTER_ASSERT(reporter, 0);
430 } 485 }
486 reporter->bumpTestCount();
431 return result == 0; 487 return result == 0;
432 } 488 }
433 489
434 const int maxThreadsAllocated = 64; 490 const int maxThreadsAllocated = 64;
435 static int maxThreads = 1; 491 static int maxThreads = 1;
436 static int threadIndex;
437 State4 threadState[maxThreadsAllocated];
438 static int testNumber;
439 static const char* testName;
440 static bool debugThreads = false;
441 492
442 State4* State4::queue = NULL; 493 SK_DECLARE_STATIC_MUTEX(gQueueMutex);
443 494
444 #if HARD_CODE_PTHREAD 495 int initializeTests(const char* test) {
445 pthread_mutex_t State4::addQueue = PTHREAD_MUTEX_INITIALIZER; 496 #ifdef SK_DEBUG
446 pthread_cond_t State4::checkQueue = PTHREAD_COND_INITIALIZER; 497 gDebugMaxWindSum = 4;
447 #else 498 gDebugMaxWindValue = 4;
448 SK_DECLARE_STATIC_MUTEX(gQueueMutex);
449 #endif 499 #endif
450
451 State4::State4() {
452 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 150 * 2, 100);
453 bitmap.allocPixels();
454 }
455
456 void createThread(State4* statePtr, ThreadFunction testFun) {
457 #if HARD_CODE_PTHREAD
458 SkDEBUGCODE(int threadError =) pthread_create(&statePtr->threadID, NULL, tes tFun,
459 (void*) statePtr);
460 SkASSERT(!threadError);
461 #else
462 statePtr->thread = new SkThread(testFun, (void*) statePtr);
463 statePtr->thread->start();
464 #endif
465 }
466
467 int dispatchTest4(ThreadFunction testFun, int a, int b, int c, int d) {
468 int testsRun = 0;
469 State4* statePtr;
470 if (!gRunTestsInOneThread) {
471 #if HARD_CODE_PTHREAD
472 pthread_mutex_lock(&State4::addQueue);
473 #else
474 SkAutoMutexAcquire aq(&gQueueMutex);
475 #endif
476 if (threadIndex < maxThreads) {
477 statePtr = &threadState[threadIndex];
478 statePtr->testsRun = 0;
479 statePtr->a = a;
480 statePtr->b = b;
481 statePtr->c = c;
482 statePtr->d = d;
483 statePtr->done = false;
484 statePtr->index = threadIndex;
485 statePtr->last = false;
486 if (debugThreads) SkDebugf("%s %d create done=%d last=%d\n", __FUNCT ION__,
487 statePtr->index, statePtr->done, statePtr->last);
488 #if HARD_CODE_PTHREAD
489 pthread_cond_init(&statePtr->initialized, NULL);
490 #else
491 // statePtr->thread contains fData which points to SkThread_PThreadD ata which
492 // contains PThreadEvent fStarted, all of which is initialized by cr eateThread below
493 #endif
494 ++threadIndex;
495 createThread(statePtr, testFun);
496 } else {
497 while (!State4::queue) {
498 if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__);
499 #if HARD_CODE_PTHREAD
500 pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
501 #else
502 // incomplete
503 #endif
504 }
505 statePtr = State4::queue;
506 testsRun += statePtr->testsRun;
507 statePtr->testsRun = 0;
508 statePtr->a = a;
509 statePtr->b = b;
510 statePtr->c = c;
511 statePtr->d = d;
512 statePtr->done = false;
513 State4::queue = NULL;
514 for (int index = 0; index < maxThreads; ++index) {
515 if (threadState[index].done) {
516 State4::queue = &threadState[index];
517 }
518 }
519 if (debugThreads) SkDebugf("%s %d init done=%d last=%d queued=%d\n", __FUNCTION__,
520 statePtr->index, statePtr->done, statePtr->last,
521 State4::queue ? State4::queue->index : -1);
522 #if HARD_CODE_PTHREAD
523 pthread_cond_signal(&statePtr->initialized);
524 #else
525 // incomplete
526 #endif
527 }
528 #if HARD_CODE_PTHREAD
529 pthread_mutex_unlock(&State4::addQueue);
530 #endif
531 } else {
532 statePtr = &threadState[0];
533 testsRun += statePtr->testsRun;
534 statePtr->testsRun = 0;
535 statePtr->a = a;
536 statePtr->b = b;
537 statePtr->c = c;
538 statePtr->d = d;
539 statePtr->done = false;
540 statePtr->index = threadIndex;
541 statePtr->last = false;
542 (*testFun)(statePtr);
543 }
544 return testsRun;
545 }
546
547 void initializeTests(skiatest::Reporter* reporter, const char* test, size_t test NameSize) {
548 testName = test; 500 testName = test;
501 size_t testNameSize = strlen(test);
549 if (!gRunTestsInOneThread) { 502 if (!gRunTestsInOneThread) {
550 int threads = -1; 503 int threads = -1;
551 #ifdef SK_BUILD_FOR_MAC 504 #ifdef SK_BUILD_FOR_MAC
552 size_t size = sizeof(threads); 505 size_t size = sizeof(threads);
553 sysctlbyname("hw.logicalcpu_max", &threads, &size, NULL, 0); 506 sysctlbyname("hw.logicalcpu_max", &threads, &size, NULL, 0);
554 #endif 507 #endif
555 if (threads > 0) { 508 if (threads > 0) {
556 maxThreads = threads; 509 maxThreads = threads;
557 } else { 510 } else {
558 maxThreads = 8; 511 maxThreads = 16;
559 } 512 }
560 } 513 }
561 SkFILEStream inFile("../../experimental/Intersection/op.htm"); 514 SkFILEStream inFile("../../experimental/Intersection/op.htm");
562 if (inFile.isValid()) { 515 if (inFile.isValid()) {
563 SkTDArray<char> inData; 516 SkTDArray<char> inData;
564 inData.setCount(inFile.getLength()); 517 inData.setCount(inFile.getLength());
565 size_t inLen = inData.count(); 518 size_t inLen = inData.count();
566 inFile.read(inData.begin(), inLen); 519 inFile.read(inData.begin(), inLen);
567 inFile.setPath(NULL); 520 inFile.setPath(NULL);
568 char* insert = strstr(inData.begin(), marker); 521 char* insert = strstr(inData.begin(), marker);
569 if (insert) { 522 if (insert) {
570 insert += sizeof(marker) - 1; 523 insert += sizeof(marker) - 1;
571 const char* numLoc = insert + 4 /* indent spaces */ + testNameSize - 1; 524 const char* numLoc = insert + 4 /* indent spaces */ + testNameSize - 1;
572 testNumber = atoi(numLoc) + 1; 525 testNumber = atoi(numLoc) + 1;
573 } 526 }
574 } 527 }
575 const char* filename = "debugXX.txt"; 528 return maxThreads;
576 for (int index = 0; index < maxThreads; ++index) {
577 State4* statePtr = &threadState[index];
578 statePtr->reporter = reporter;
579 strcpy(statePtr->filename, filename);
580 size_t len = strlen(filename);
581 SkASSERT(statePtr->filename[len - 6] == 'X');
582 SkASSERT(statePtr->filename[len - 5] == 'X');
583 statePtr->filename[len - 6] = '0' + index / 10;
584 statePtr->filename[len - 5] = '0' + index % 10;
585 }
586 threadIndex = 0;
587 } 529 }
588 530
589 void outputProgress(const State4& state, const char* pathStr, SkPath::FillType p athFillType) { 531 void outputProgress(char* ramStr, const char* pathStr, SkPath::FillType pathFill Type) {
590 if (gRunTestsInOneThread && gShowOutputProgress) { 532 const char testFunction[] = "testSimplify(path);";
591 if (pathFillType == SkPath::kEvenOdd_FillType) {
592 SkDebugf(" path.setFillType(SkPath::kEvenOdd_FillType);\n", pathS tr);
593 }
594 SkDebugf("%s\n", pathStr);
595 }
596 const char testFunction[] = "testSimplifyx(path);";
597 const char* pathPrefix = NULL; 533 const char* pathPrefix = NULL;
598 const char* nameSuffix = NULL; 534 const char* nameSuffix = NULL;
599 if (pathFillType == SkPath::kEvenOdd_FillType) { 535 if (pathFillType == SkPath::kEvenOdd_FillType) {
600 pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; 536 pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n";
601 nameSuffix = "x"; 537 nameSuffix = "x";
602 } 538 }
603 if (gUsePhysicalFiles) { 539 SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE);
604 SkFILEWStream outFile(state.filename); 540 outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, rRamStr eam);
605 if (!outFile.isValid()) {
606 SkASSERT(0);
607 return;
608 }
609 outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, out File);
610 return;
611 }
612 state.ramStream.reset();
613 outputToStream(state, pathStr, pathPrefix, nameSuffix, testFunction, state.r amStream);
614 } 541 }
615 542
616 void outputProgress(const State4& state, const char* pathStr, SkPathOp op) { 543 void outputProgress(char* ramStr, const char* pathStr, SkPathOp op) {
617 SkString testFunc("testPathOp(path, pathB, "); 544 const char testFunction[] = "testOp(path);";
618 testFunc += opStrs[op]; 545 SkASSERT(op < sizeof(opSuffixes) / sizeof(opSuffixes[0]));
619 testFunc += ");";
620 const char* testFunction = testFunc.c_str();
621 if (gRunTestsInOneThread && gShowOutputProgress) {
622 SkDebugf("%s\n", pathStr);
623 SkDebugf(" %s\n", testFunction);
624 }
625 const char* nameSuffix = opSuffixes[op]; 546 const char* nameSuffix = opSuffixes[op];
626 if (gUsePhysicalFiles) { 547 SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE);
627 SkFILEWStream outFile(state.filename); 548 outputToStream(pathStr, NULL, nameSuffix, testFunction, true, rRamStream);
628 if (!outFile.isValid()) {
629 SkASSERT(0);
630 return;
631 }
632 outputToStream(state, pathStr, NULL, nameSuffix, testFunction, outFile);
633 return;
634 }
635 state.ramStream.reset();
636 outputToStream(state, pathStr, NULL, nameSuffix, testFunction, state.ramStre am);
637 }
638
639 static void writeTestName(const char* nameSuffix, SkWStream& outFile) {
640 outFile.writeText(testName);
641 outFile.writeDecAsText(testNumber);
642 if (nameSuffix) {
643 outFile.writeText(nameSuffix);
644 }
645 }
646
647 void outputToStream(const State4& state, const char* pathStr, const char* pathPr efix,
648 const char* nameSuffix,
649 const char* testFunction, SkWStream& outFile) {
650 outFile.writeText("<div id=\"");
651 writeTestName(nameSuffix, outFile);
652 outFile.writeText("\">\n");
653 if (pathPrefix) {
654 outFile.writeText(pathPrefix);
655 }
656 outFile.writeText(pathStr);
657 outFile.writeText("</div>\n\n");
658
659 outFile.writeText(marker);
660 outFile.writeText(" ");
661 writeTestName(nameSuffix, outFile);
662 outFile.writeText(",\n\n\n");
663
664 outFile.writeText("static void ");
665 writeTestName(nameSuffix, outFile);
666 outFile.writeText("() {\n SkPath path");
667 if (!pathPrefix) {
668 outFile.writeText(", pathB");
669 }
670 outFile.writeText(";\n");
671 if (pathPrefix) {
672 outFile.writeText(pathPrefix);
673 }
674 outFile.writeText(pathStr);
675 outFile.writeText(" ");
676 outFile.writeText(testFunction);
677 outFile.writeText("\n}\n\n");
678 outFile.writeText("static void (*firstTest)() = ");
679 writeTestName(nameSuffix, outFile);
680 outFile.writeText(";\n\n");
681
682 outFile.writeText("static struct {\n");
683 outFile.writeText(" void (*fun)();\n");
684 outFile.writeText(" const char* str;\n");
685 outFile.writeText("} tests[] = {\n");
686 outFile.writeText(" TEST(");
687 writeTestName(nameSuffix, outFile);
688 outFile.writeText("),\n");
689 outFile.flush();
690 }
691
692 bool runNextTestSet(State4& state) {
693 if (gRunTestsInOneThread) {
694 return false;
695 }
696 #if HARD_CODE_PTHREAD
697 pthread_mutex_lock(&State4::addQueue);
698 #else
699 SkAutoMutexAcquire aq(&gQueueMutex);
700 #endif
701 state.done = true;
702 State4::queue = &state;
703 if (debugThreads) SkDebugf("%s %d checkQueue done=%d last=%d\n", __FUNCTION_ _, state.index,
704 state.done, state.last);
705 #if HARD_CODE_PTHREAD
706 pthread_cond_signal(&State4::checkQueue);
707 #else
708 // incomplete
709 #endif
710 while (state.done && !state.last) {
711 if (debugThreads) SkDebugf("%s %d done=%d last=%d\n", __FUNCTION__, stat e.index, state.done, state.last);
712 #if HARD_CODE_PTHREAD
713 pthread_cond_wait(&state.initialized, &State4::addQueue);
714 #else
715 // incomplete
716 #endif
717 }
718 #if HARD_CODE_PTHREAD
719 pthread_mutex_unlock(&State4::addQueue);
720 #endif
721 return !state.last;
722 }
723
724 int waitForCompletion() {
725 int testsRun = 0;
726 if (!gRunTestsInOneThread) {
727 #if HARD_CODE_PTHREAD
728 pthread_mutex_lock(&State4::addQueue);
729 #else
730 SkAutoMutexAcquire aq(gQueueMutex);
731 #endif
732 int runningThreads = threadIndex;
733 int index;
734 while (runningThreads > 0) {
735 while (!State4::queue) {
736 if (debugThreads) SkDebugf("%s checkQueue\n", __FUNCTION__);
737 #if HARD_CODE_PTHREAD
738 pthread_cond_wait(&State4::checkQueue, &State4::addQueue);
739 #else
740 // ioncomplete
741 #endif
742 }
743 while (State4::queue) {
744 --runningThreads;
745 #if DEBUG_SHOW_TEST_PROGRESS
746 SkDebugf("•");
747 #endif
748 State4::queue->last = true;
749 State4* next = NULL;
750 for (index = 0; index < maxThreads; ++index) {
751 State4& test = threadState[index];
752 if (test.done && !test.last) {
753 next = &test;
754 }
755 }
756 if (debugThreads) SkDebugf("%s %d next=%d deQueue\n", __FUNCTION __,
757 State4::queue->index, next ? next->index : -1);
758 #if HARD_CODE_PTHREAD
759 pthread_cond_signal(&State4::queue->initialized);
760 #else
761 // incomplete
762 #endif
763 State4::queue = next;
764 }
765 }
766 #if HARD_CODE_PTHREAD
767 pthread_mutex_unlock(&State4::addQueue);
768 #endif
769 for (index = 0; index < maxThreads; ++index) {
770 #if HARD_CODE_PTHREAD
771 pthread_join(threadState[index].threadID, NULL);
772 #else
773 threadState[index].thread->join();
774 delete threadState[index].thread;
775 #endif
776 testsRun += threadState[index].testsRun;
777 }
778 #if DEBUG_SHOW_TEST_PROGRESS
779 SkDebugf("\n");
780 #endif
781 }
782 #ifdef SK_DEBUG
783 gDebugMaxWindSum = SK_MaxS32;
784 gDebugMaxWindValue = SK_MaxS32;
785 #endif
786 return testsRun;
787 } 549 }
788 550
789 void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count, 551 void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count,
790 void (*firstTest)(skiatest::Reporter* ), 552 void (*firstTest)(skiatest::Reporter* ),
791 void (*stopTest)(skiatest::Reporter* ), bool reverse) { 553 void (*stopTest)(skiatest::Reporter* ), bool reverse) {
792 size_t index; 554 size_t index;
793 if (firstTest) { 555 if (firstTest) {
794 index = count - 1; 556 index = count - 1;
795 while (index > 0 && tests[index].fun != firstTest) { 557 while (index > 0 && tests[index].fun != firstTest) {
796 --index; 558 --index;
(...skipping 16 matching lines...) Expand all
813 } 575 }
814 if (tests[index].fun == stopTest) { 576 if (tests[index].fun == stopTest) {
815 SkDebugf("lastTest\n"); 577 SkDebugf("lastTest\n");
816 } 578 }
817 if (index == last) { 579 if (index == last) {
818 break; 580 break;
819 } 581 }
820 index += reverse ? -1 : 1; 582 index += reverse ? -1 : 1;
821 } while (true); 583 } while (true);
822 } 584 }
OLDNEW
« no previous file with comments | « tests/PathOpsExtendedTest.h ('k') | tests/PathOpsOpCubicThreadedTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698