SkpSkGrTest.cpp revision b2d93a91222dac2edb3c19128fd58fa2e74272aa
1#if !SK_SUPPORT_GPU 2#error "GPU support required" 3#endif 4 5#include "GrContext.h" 6#include "GrContextFactory.h" 7#include "GrRenderTarget.h" 8#include "SkGpuDevice.h" 9#include "gl/GrGLDefines.h" 10 11#include "SkBitmap.h" 12#include "SkCanvas.h" 13#include "SkColor.h" 14#include "SkDevice.h" 15#include "SkGraphics.h" 16#include "SkImageDecoder.h" 17#include "SkImageEncoder.h" 18#include "SkOSFile.h" 19#include "SkPicture.h" 20#include "SkRTConf.h" 21#include "SkRunnable.h" 22#include "SkStream.h" 23#include "SkString.h" 24#include "SkTArray.h" 25#include "SkTDArray.h" 26#include "SkThreadPool.h" 27#include "SkTime.h" 28#include "Test.h" 29 30#ifdef SK_BUILD_FOR_WIN 31 #define PATH_SLASH "\\" 32 #define IN_DIR "D:\\9-30-13\\" 33 #define OUT_DIR "D:\\skpSkGr\\11\\" 34 #define LINE_FEED "\r\n" 35#else 36 #define PATH_SLASH "/" 37 #define IN_DIR "/usr/local/google/home/caryclark" PATH_SLASH "9-30-13-skp" 38 #define OUT_DIR "/media/01CD75512A7F9EE0/4" PATH_SLASH 39 #define LINE_FEED "\n" 40#endif 41 42#define PATH_STR_SIZE 512 43 44static const struct { 45 int directory; 46 const char* filename; 47} skipOverSkGr[] = { 48 {1, "http___accuweather_com_.skp"}, // Couldn't convert bitmap to texture.http___absoku072_com_ 49}; 50 51static const size_t skipOverSkGrCount = 0; // SK_ARRAY_COUNT(skipOverSkGr); 52 53///////////////////////////////////////// 54 55class SkpSkGrThreadedRunnable; 56 57enum TestStep { 58 kCompareBits, 59 kEncodeFiles, 60}; 61 62enum { 63 kMaxLength = 128, 64 kMaxFiles = 128, 65}; 66 67struct TestResult { 68 void init(int dirNo) { 69 fDirNo = dirNo; 70 sk_bzero(fFilename, sizeof(fFilename)); 71 fTestStep = kCompareBits; 72 fScaleOversized = true; 73 } 74 75 SkString status() { 76 SkString outStr; 77 outStr.printf("%s %d %d%s", fFilename, fPixelError, fTime, LINE_FEED); 78 return outStr; 79 } 80 81 static void Test(int dirNo, const char* filename, TestStep testStep, bool verbose) { 82 TestResult test; 83 test.init(dirNo); 84 test.fTestStep = testStep; 85 strcpy(test.fFilename, filename); 86 test.testOne(); 87 if (verbose) { 88 SkDebugf("%s", test.status().c_str()); 89 } 90 } 91 92 void test(int dirNo, const SkString& filename) { 93 init(dirNo); 94 strcpy(fFilename, filename.c_str()); 95 testOne(); 96 } 97 98 void testOne(); 99 100 char fFilename[kMaxLength]; 101 TestStep fTestStep; 102 int fDirNo; 103 int fPixelError; 104 int fTime; 105 bool fScaleOversized; 106}; 107 108struct SkpSkGrThreadState { 109 void init(int dirNo) { 110 fResult.init(dirNo); 111 fFoundCount = 0; 112 fSmallestError = 0; 113 sk_bzero(fFilesFound, sizeof(fFilesFound)); 114 sk_bzero(fDirsFound, sizeof(fDirsFound)); 115 sk_bzero(fError, sizeof(fError)); 116 } 117 118 char fFilesFound[kMaxFiles][kMaxLength]; 119 int fDirsFound[kMaxFiles]; 120 int fError[kMaxFiles]; 121 int fFoundCount; 122 int fSmallestError; 123 skiatest::Reporter* fReporter; 124 TestResult fResult; 125}; 126 127struct SkpSkGrThreadedTestRunner { 128 SkpSkGrThreadedTestRunner(skiatest::Reporter* reporter, int threadCount) 129 : fNumThreads(threadCount) 130 , fReporter(reporter) { 131 } 132 133 ~SkpSkGrThreadedTestRunner(); 134 void render(); 135 int fNumThreads; 136 SkTDArray<SkpSkGrThreadedRunnable*> fRunnables; 137 skiatest::Reporter* fReporter; 138}; 139 140class SkpSkGrThreadedRunnable : public SkRunnable { 141public: 142 SkpSkGrThreadedRunnable(void (*testFun)(SkpSkGrThreadState*), int dirNo, const char* str, 143 SkpSkGrThreadedTestRunner* runner) { 144 SkASSERT(strlen(str) < sizeof(fState.fResult.fFilename) - 1); 145 fState.init(dirNo); 146 strcpy(fState.fResult.fFilename, str); 147 fState.fReporter = runner->fReporter; 148 fTestFun = testFun; 149 } 150 151 virtual void run() SK_OVERRIDE { 152 SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024); 153 (*fTestFun)(&fState); 154 } 155 156 SkpSkGrThreadState fState; 157 void (*fTestFun)(SkpSkGrThreadState*); 158}; 159 160SkpSkGrThreadedTestRunner::~SkpSkGrThreadedTestRunner() { 161 for (int index = 0; index < fRunnables.count(); index++) { 162 SkDELETE(fRunnables[index]); 163 } 164} 165 166void SkpSkGrThreadedTestRunner::render() { 167 SkThreadPool pool(fNumThreads); 168 for (int index = 0; index < fRunnables.count(); ++ index) { 169 pool.add(fRunnables[index]); 170 } 171} 172 173//////////////////////////////////////////////// 174 175static const char outGrDir[] = OUT_DIR "grTest"; 176static const char outSkDir[] = OUT_DIR "skTest"; 177static const char outSkpDir[] = OUT_DIR "skpTest"; 178static const char outDiffDir[] = OUT_DIR "outTest"; 179static const char outStatusDir[] = OUT_DIR "statusTest"; 180 181static SkString make_filepath(int dirIndex, const char* dir, const char* name) { 182 SkString path(dir); 183 if (dirIndex) { 184 path.appendf("%d", dirIndex); 185 } 186 path.append(PATH_SLASH); 187 path.append(name); 188 return path; 189} 190 191static SkString make_in_dir_name(int dirIndex) { 192 SkString dirName(IN_DIR); 193 dirName.appendf("%d", dirIndex); 194 if (!sk_exists(dirName.c_str())) { 195 SkDebugf("could not read dir %s\n", dirName.c_str()); 196 return SkString(); 197 } 198 return dirName; 199} 200 201static bool make_out_dirs() { 202 SkString outDir = make_filepath(0, OUT_DIR, ""); 203 if (!sk_exists(outDir.c_str())) { 204 if (!sk_mkdir(outDir.c_str())) { 205 SkDebugf("could not create dir %s\n", outDir.c_str()); 206 return false; 207 } 208 } 209 SkString grDir = make_filepath(0, outGrDir, ""); 210 if (!sk_exists(grDir.c_str())) { 211 if (!sk_mkdir(grDir.c_str())) { 212 SkDebugf("could not create dir %s\n", grDir.c_str()); 213 return false; 214 } 215 } 216 SkString skDir = make_filepath(0, outSkDir, ""); 217 if (!sk_exists(skDir.c_str())) { 218 if (!sk_mkdir(skDir.c_str())) { 219 SkDebugf("could not create dir %s\n", skDir.c_str()); 220 return false; 221 } 222 } 223 SkString skpDir = make_filepath(0, outSkpDir, ""); 224 if (!sk_exists(skpDir.c_str())) { 225 if (!sk_mkdir(skpDir.c_str())) { 226 SkDebugf("could not create dir %s\n", skpDir.c_str()); 227 return false; 228 } 229 } 230 SkString diffDir = make_filepath(0, outDiffDir, ""); 231 if (!sk_exists(diffDir.c_str())) { 232 if (!sk_mkdir(diffDir.c_str())) { 233 SkDebugf("could not create dir %s\n", diffDir.c_str()); 234 return false; 235 } 236 } 237 SkString statusDir = make_filepath(0, outStatusDir, ""); 238 if (!sk_exists(statusDir.c_str())) { 239 if (!sk_mkdir(statusDir.c_str())) { 240 SkDebugf("could not create dir %s\n", statusDir.c_str()); 241 return false; 242 } 243 } 244 return true; 245} 246 247static SkString make_png_name(const char* filename) { 248 SkString pngName = SkString(filename); 249 pngName.remove(pngName.size() - 3, 3); 250 pngName.append("png"); 251 return pngName; 252} 253 254typedef GrContextFactory::GLContextType GLContextType; 255#ifdef SK_BUILD_FOR_WIN 256static const GLContextType kAngle = GrContextFactory::kANGLE_GLContextType; 257#else 258static const GLContextType kNative = GrContextFactory::kNative_GLContextType; 259#endif 260 261static int similarBits(const SkBitmap& gr, const SkBitmap& sk) { 262 const int kRowCount = 3; 263 const int kThreshold = 3; 264 int width = SkTMin(gr.width(), sk.width()); 265 if (width < kRowCount) { 266 return true; 267 } 268 int height = SkTMin(gr.height(), sk.height()); 269 if (height < kRowCount) { 270 return true; 271 } 272 int errorTotal = 0; 273 SkTArray<char, true> errorRows; 274 errorRows.push_back_n(width * kRowCount); 275 SkAutoLockPixels autoGr(gr); 276 SkAutoLockPixels autoSk(sk); 277 char* base = &errorRows[0]; 278 for (int y = 0; y < height; ++y) { 279 SkPMColor* grRow = gr.getAddr32(0, y); 280 SkPMColor* skRow = sk.getAddr32(0, y); 281 char* cOut = &errorRows[(y % kRowCount) * width]; 282 for (int x = 0; x < width; ++x) { 283 SkPMColor grColor = grRow[x]; 284 SkPMColor skColor = skRow[x]; 285 int dr = SkGetPackedR32(grColor) - SkGetPackedR32(skColor); 286 int dg = SkGetPackedG32(grColor) - SkGetPackedG32(skColor); 287 int db = SkGetPackedB32(grColor) - SkGetPackedB32(skColor); 288 int error = SkTMax(SkAbs32(dr), SkTMax(SkAbs32(dg), SkAbs32(db))); 289 if ((cOut[x] = error >= kThreshold) && x >= 2 290 && base[x - 2] && base[width + x - 2] && base[width * 2 + x - 2] 291 && base[x - 1] && base[width + x - 1] && base[width * 2 + x - 1] 292 && base[x - 0] && base[width + x - 0] && base[width * 2 + x - 0]) { 293 errorTotal += error; 294 } 295 } 296 } 297 return errorTotal; 298} 299 300static bool addError(SkpSkGrThreadState* data) { 301 bool foundSmaller = false; 302 int dCount = data->fFoundCount; 303 int pixelError = data->fResult.fPixelError; 304 if (data->fFoundCount < kMaxFiles) { 305 data->fError[dCount] = pixelError; 306 strcpy(data->fFilesFound[dCount], data->fResult.fFilename); 307 data->fDirsFound[dCount] = data->fResult.fDirNo; 308 ++data->fFoundCount; 309 } else if (pixelError > data->fSmallestError) { 310 int smallest = SK_MaxS32; 311 int smallestIndex = 0; 312 for (int index = 0; index < kMaxFiles; ++index) { 313 if (smallest > data->fError[index]) { 314 smallest = data->fError[index]; 315 smallestIndex = index; 316 } 317 } 318 data->fError[smallestIndex] = pixelError; 319 strcpy(data->fFilesFound[smallestIndex], data->fResult.fFilename); 320 data->fDirsFound[smallestIndex] = data->fResult.fDirNo; 321 data->fSmallestError = SK_MaxS32; 322 for (int index = 0; index < kMaxFiles; ++index) { 323 if (data->fSmallestError > data->fError[index]) { 324 data->fSmallestError = data->fError[index]; 325 } 326 } 327 SkDebugf("*%d*", data->fSmallestError); 328 foundSmaller = true; 329 } 330 return foundSmaller; 331} 332 333static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) { 334 canvas->save(); 335 int pWidth = pic->width(); 336 int pHeight = pic->height(); 337 const int maxDimension = 1000; 338 const int slices = 3; 339 int xInterval = SkTMax(pWidth - maxDimension, 0) / (slices - 1); 340 int yInterval = SkTMax(pHeight - maxDimension, 0) / (slices - 1); 341 SkRect rect = {0, 0, SkIntToScalar(SkTMin(maxDimension, pWidth)), 342 SkIntToScalar(SkTMin(maxDimension, pHeight))}; 343 canvas->clipRect(rect); 344 SkMSec start = SkTime::GetMSecs(); 345 for (int x = 0; x < slices; ++x) { 346 for (int y = 0; y < slices; ++y) { 347 pic->draw(canvas); 348 canvas->translate(0, SkIntToScalar(yInterval)); 349 } 350 canvas->translate(SkIntToScalar(xInterval), SkIntToScalar(-yInterval * slices)); 351 } 352 SkMSec end = SkTime::GetMSecs(); 353 canvas->restore(); 354 return end - start; 355} 356 357static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) { 358 canvas->clear(SK_ColorWHITE); 359 if (scale != 1) { 360 canvas->save(); 361 canvas->scale(1.0f / scale, 1.0f / scale); 362 } 363 pic->draw(canvas); 364 if (scale != 1) { 365 canvas->restore(); 366 } 367} 368 369static void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) { 370 SkString outFile = make_filepath(0, outDir, pngName); 371 if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, 372 SkImageEncoder::kPNG_Type, 100)) { 373 SkDebugf("unable to encode gr %s (width=%d height=%d)br \n", pngName, 374 bitmap.width(), bitmap.height()); 375 } 376} 377 378void TestResult::testOne() { 379 SkPicture* pic = NULL; 380 { 381 SkString d; 382 d.printf(" {%d, \"%s\"},", fDirNo, fFilename); 383 SkString path = make_filepath(fDirNo, IN_DIR, fFilename); 384 SkFILEStream stream(path.c_str()); 385 if (!stream.isValid()) { 386 SkDebugf("invalid stream %s\n", path.c_str()); 387 goto finish; 388 } 389 if (fTestStep == kEncodeFiles) { 390 size_t length = stream.getLength(); 391 SkTArray<char, true> bytes; 392 bytes.push_back_n(length); 393 stream.read(&bytes[0], length); 394 stream.rewind(); 395 SkString wPath = make_filepath(0, outSkpDir, fFilename); 396 SkFILEWStream wStream(wPath.c_str()); 397 wStream.write(&bytes[0], length); 398 wStream.flush(); 399 } 400 pic = SkPicture::CreateFromStream(&stream, &SkImageDecoder::DecodeMemory); 401 if (!pic) { 402 SkDebugf("unable to decode %s\n", fFilename); 403 goto finish; 404 } 405 int pWidth = pic->width(); 406 int pHeight = pic->height(); 407 int pLargerWH = SkTMax(pWidth, pHeight); 408 GrContextFactory contextFactory; 409#ifdef SK_BUILD_FOR_WIN 410 GrContext* context = contextFactory.get(kAngle); 411#else 412 GrContext* context = contextFactory.get(kNative); 413#endif 414 if (NULL == context) { 415 SkDebugf("unable to allocate context for %s\n", fFilename); 416 goto finish; 417 } 418 int maxWH = context->getMaxRenderTargetSize(); 419 int scale = 1; 420 while (pLargerWH / scale > maxWH) { 421 scale *= 2; 422 } 423 SkBitmap bitmap; 424 SkIPoint dim; 425 do { 426 dim.fX = (pWidth + scale - 1) / scale; 427 dim.fY = (pHeight + scale - 1) / scale; 428 bool success = bitmap.allocN32Pixels(, dim.fX, dim.fY); 429 if (success) { 430 break; 431 } 432 SkDebugf("-%d-", scale); 433 } while ((scale *= 2) < 256); 434 if (scale >= 256) { 435 SkDebugf("unable to allocate bitmap for %s (w=%d h=%d) (sw=%d sh=%d)\n", 436 fFilename, pWidth, pHeight, dim.fX, dim.fY); 437 goto finish; 438 } 439 SkCanvas skCanvas(bitmap); 440 drawPict(pic, &skCanvas, fScaleOversized ? scale : 1); 441 GrTextureDesc desc; 442 desc.fConfig = kSkia8888_GrPixelConfig; 443 desc.fFlags = kRenderTarget_GrTextureFlagBit; 444 desc.fWidth = dim.fX; 445 desc.fHeight = dim.fY; 446 desc.fSampleCnt = 0; 447 SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0)); 448 if (!texture) { 449 SkDebugf("unable to allocate texture for %s (w=%d h=%d)\n", fFilename, 450 dim.fX, dim.fY); 451 goto finish; 452 } 453 SkGpuDevice grDevice(context, texture.get()); 454 SkCanvas grCanvas(&grDevice); 455 drawPict(pic, &grCanvas, fScaleOversized ? scale : 1); 456 457 SkBitmap grBitmap; 458 grBitmap.allocPixels(grCanvas.imageInfo()); 459 grCanvas.readPixels(&grBitmap, 0, 0); 460 461 if (fTestStep == kCompareBits) { 462 fPixelError = similarBits(grBitmap, bitmap); 463 int skTime = timePict(pic, &skCanvas); 464 int grTime = timePict(pic, &grCanvas); 465 fTime = skTime - grTime; 466 } else if (fTestStep == kEncodeFiles) { 467 SkString pngStr = make_png_name(fFilename); 468 const char* pngName = pngStr.c_str(); 469 writePict(grBitmap, outGrDir, pngName); 470 writePict(bitmap, outSkDir, pngName); 471 } 472 } 473finish: 474 SkDELETE(pic); 475} 476 477static SkString makeStatusString(int dirNo) { 478 SkString statName; 479 statName.printf("stats%d.txt", dirNo); 480 SkString statusFile = make_filepath(0, outStatusDir, statName.c_str()); 481 return statusFile; 482} 483 484class PreParser { 485public: 486 PreParser(int dirNo) 487 : fDirNo(dirNo) 488 , fIndex(0) 489 , fStatusPath(makeStatusString(dirNo)) { 490 if (!sk_exists(fStatusPath.c_str())) { 491 return; 492 } 493 SkFILEStream reader; 494 reader.setPath(fStatusPath.c_str()); 495 while (fetch(reader, &fResults.push_back())) 496 ; 497 fResults.pop_back(); 498 } 499 500 bool fetch(SkFILEStream& reader, TestResult* result) { 501 char c; 502 int i = 0; 503 result->init(fDirNo); 504 result->fPixelError = 0; 505 result->fTime = 0; 506 do { 507 bool readOne = reader.read(&c, 1) != 0; 508 if (!readOne) { 509 SkASSERT(i == 0); 510 return false; 511 } 512 if (c == ' ') { 513 result->fFilename[i++] = '\0'; 514 break; 515 } 516 result->fFilename[i++] = c; 517 SkASSERT(i < kMaxLength); 518 } while (true); 519 do { 520 SkAssertResult(reader.read(&c, 1) != 0); 521 if (c == ' ') { 522 break; 523 } 524 SkASSERT(c >= '0' && c <= '9'); 525 result->fPixelError = result->fPixelError * 10 + (c - '0'); 526 } while (true); 527 bool minus = false; 528 do { 529 if (reader.read(&c, 1) == 0) { 530 break; 531 } 532 if (c == '\r' && reader.read(&c, 1) == 0) { 533 break; 534 } 535 if (c == '\n') { 536 break; 537 } 538 if (c == '-') { 539 minus = true; 540 continue; 541 } 542 SkASSERT(c >= '0' && c <= '9'); 543 result->fTime = result->fTime * 10 + (c - '0'); 544 } while (true); 545 if (minus) { 546 result->fTime = -result->fTime; 547 } 548 return true; 549 } 550 551 bool match(const SkString& filename, SkFILEWStream* stream, TestResult* result) { 552 if (fIndex < fResults.count()) { 553 *result = fResults[fIndex++]; 554 SkASSERT(filename.equals(result->fFilename)); 555 SkString outStr(result->status()); 556 stream->write(outStr.c_str(), outStr.size()); 557 stream->flush(); 558 return true; 559 } 560 return false; 561 } 562 563private: 564 int fDirNo; 565 int fIndex; 566 SkTArray<TestResult, true> fResults; 567 SkString fStatusPath; 568}; 569 570static bool initTest() { 571#if !defined SK_BUILD_FOR_WIN && !defined SK_BUILD_FOR_MAC 572 SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true); 573 SK_CONF_SET("images.png.suppressDecoderWarnings", true); 574#endif 575 return make_out_dirs(); 576} 577 578DEF_TEST(SkpSkGr, reporter) { 579 SkTArray<TestResult, true> errors; 580 if (!initTest()) { 581 return; 582 } 583 SkpSkGrThreadState state; 584 state.init(0); 585 int smallCount = 0; 586 for (int dirNo = 1; dirNo <= 100; ++dirNo) { 587 SkString pictDir = make_in_dir_name(dirNo); 588 SkASSERT(pictDir.size()); 589 if (reporter->verbose()) { 590 SkDebugf("dirNo=%d\n", dirNo); 591 } 592 SkOSFile::Iter iter(pictDir.c_str(), "skp"); 593 SkString filename; 594 int testCount = 0; 595 PreParser preParser(dirNo); 596 SkFILEWStream statusStream(makeStatusString(dirNo).c_str()); 597 while (iter.next(&filename)) { 598 for (size_t index = 0; index < skipOverSkGrCount; ++index) { 599 if (skipOverSkGr[index].directory == dirNo 600 && strcmp(filename.c_str(), skipOverSkGr[index].filename) == 0) { 601 goto skipOver; 602 } 603 } 604 if (preParser.match(filename, &statusStream, &state.fResult)) { 605 addError(&state); 606 ++testCount; 607 goto checkEarlyExit; 608 } 609 if (state.fSmallestError > 5000000) { 610 goto breakOut; 611 } 612 { 613 TestResult& result = state.fResult; 614 result.test(dirNo, filename); 615 SkString outStr(result.status()); 616 statusStream.write(outStr.c_str(), outStr.size()); 617 statusStream.flush(); 618 if (1) { 619 SkDebugf("%s", outStr.c_str()); 620 } 621 bool noMatch = addError(&state); 622 if (noMatch) { 623 smallCount = 0; 624 } else if (++smallCount > 10000) { 625 goto breakOut; 626 } 627 } 628 ++testCount; 629 if (reporter->verbose()) { 630 if (testCount % 100 == 0) { 631 SkDebugf("#%d\n", testCount); 632 } 633 } 634 skipOver: 635 reporter->bumpTestCount(); 636 checkEarlyExit: 637 if (1 && testCount == 20) { 638 break; 639 } 640 } 641 } 642breakOut: 643 if (reporter->verbose()) { 644 for (int index = 0; index < state.fFoundCount; ++index) { 645 SkDebugf("%d %s %d\n", state.fDirsFound[index], state.fFilesFound[index], 646 state.fError[index]); 647 } 648 } 649 for (int index = 0; index < state.fFoundCount; ++index) { 650 TestResult::Test(state.fDirsFound[index], state.fFilesFound[index], kEncodeFiles, 651 reporter->verbose()); 652 if (reporter->verbose()) SkDebugf("+"); 653 } 654} 655 656static void bumpCount(skiatest::Reporter* reporter, bool skipping) { 657 if (reporter->verbose()) { 658 static int threadTestCount; 659 sk_atomic_inc(&threadTestCount); 660 if (!skipping && threadTestCount % 100 == 0) { 661 SkDebugf("#%d\n", threadTestCount); 662 } 663 if (skipping && threadTestCount % 10000 == 0) { 664 SkDebugf("#%d\n", threadTestCount); 665 } 666 } 667} 668 669static void testSkGrMain(SkpSkGrThreadState* data) { 670 data->fResult.testOne(); 671 bumpCount(data->fReporter, false); 672 data->fReporter->bumpTestCount(); 673} 674 675DEF_TEST(SkpSkGrThreaded, reporter) { 676 if (!initTest()) { 677 return; 678 } 679 int threadCount = reporter->allowThreaded() ? 3 : 1; 680 SkpSkGrThreadedTestRunner testRunner(reporter, threadCount); 681 for (int dirIndex = 1; dirIndex <= 100; ++dirIndex) { 682 SkString pictDir = make_in_dir_name(dirIndex); 683 if (pictDir.size() == 0) { 684 continue; 685 } 686 SkOSFile::Iter iter(pictDir.c_str(), "skp"); 687 SkString filename; 688 while (iter.next(&filename)) { 689 SkString pngName = make_png_name(filename.c_str()); 690 SkString oldPng = make_filepath(dirIndex, outSkDir, pngName.c_str()); 691 SkString newPng = make_filepath(dirIndex, outGrDir, pngName.c_str()); 692 if (sk_exists(oldPng.c_str()) && sk_exists(newPng.c_str())) { 693 bumpCount(reporter, true); 694 continue; 695 } 696 for (size_t index = 0; index < skipOverSkGrCount; ++index) { 697 if (skipOverSkGr[index].directory == dirIndex 698 && strcmp(filename.c_str(), skipOverSkGr[index].filename) == 0) { 699 bumpCount(reporter, true); 700 goto skipOver; 701 } 702 } 703 *testRunner.fRunnables.append() = SkNEW_ARGS(SkpSkGrThreadedRunnable, 704 (&testSkGrMain, dirIndex, filename.c_str(), &testRunner)); 705 skipOver: 706 ; 707 } 708 } 709 testRunner.render(); 710 SkpSkGrThreadState& max = testRunner.fRunnables[0]->fState; 711 for (int dirIndex = 2; dirIndex <= 100; ++dirIndex) { 712 SkpSkGrThreadState& state = testRunner.fRunnables[dirIndex - 1]->fState; 713 for (int index = 0; index < state.fFoundCount; ++index) { 714 int maxIdx = max.fFoundCount; 715 if (maxIdx < kMaxFiles) { 716 max.fError[maxIdx] = state.fError[index]; 717 strcpy(max.fFilesFound[maxIdx], state.fFilesFound[index]); 718 max.fDirsFound[maxIdx] = state.fDirsFound[index]; 719 ++max.fFoundCount; 720 continue; 721 } 722 for (maxIdx = 0; maxIdx < max.fFoundCount; ++maxIdx) { 723 if (max.fError[maxIdx] < state.fError[index]) { 724 max.fError[maxIdx] = state.fError[index]; 725 strcpy(max.fFilesFound[maxIdx], state.fFilesFound[index]); 726 max.fDirsFound[maxIdx] = state.fDirsFound[index]; 727 break; 728 } 729 } 730 } 731 } 732 TestResult encoder; 733 encoder.fTestStep = kEncodeFiles; 734 for (int index = 0; index < max.fFoundCount; ++index) { 735 encoder.fDirNo = max.fDirsFound[index]; 736 strcpy(encoder.fFilename, max.fFilesFound[index]); 737 encoder.testOne(); 738 SkDebugf("+"); 739 } 740} 741 742DEF_TEST(SkpSkGrOneOff, reporter) { 743 if (!initTest()) { 744 return; 745 } 746 int testIndex = 166; 747 int dirIndex = skipOverSkGr[testIndex - 166].directory; 748 SkString pictDir = make_in_dir_name(dirIndex); 749 if (pictDir.size() == 0) { 750 return; 751 } 752 SkString filename(skipOverSkGr[testIndex - 166].filename); 753 TestResult::Test(dirIndex, filename.c_str(), kCompareBits, reporter->verbose()); 754 TestResult::Test(dirIndex, filename.c_str(), kEncodeFiles, reporter->verbose()); 755} 756