| OLD | NEW |
| 1 #include "CrashHandler.h" | 1 #include "CrashHandler.h" |
| 2 #include "DMJsonWriter.h" | 2 #include "DMJsonWriter.h" |
| 3 #include "DMSrcSink.h" | 3 #include "DMSrcSink.h" |
| 4 #include "DMSrcSinkAndroid.h" | 4 #include "DMSrcSinkAndroid.h" |
| 5 #include "OverwriteLine.h" | 5 #include "OverwriteLine.h" |
| 6 #include "ProcStats.h" | 6 #include "ProcStats.h" |
| 7 #include "SkBBHFactory.h" | 7 #include "SkBBHFactory.h" |
| 8 #include "SkChecksum.h" | 8 #include "SkChecksum.h" |
| 9 #include "SkCommonFlags.h" | 9 #include "SkCommonFlags.h" |
| 10 #include "SkForceLinking.h" | 10 #include "SkForceLinking.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 | 42 |
| 43 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); | 43 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); |
| 44 static SkTArray<SkString> gFailures; | 44 static SkTArray<SkString> gFailures; |
| 45 | 45 |
| 46 static void fail(ImplicitString err) { | 46 static void fail(ImplicitString err) { |
| 47 SkAutoMutexAcquire lock(gFailuresMutex); | 47 SkAutoMutexAcquire lock(gFailuresMutex); |
| 48 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); | 48 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str()); |
| 49 gFailures.push_back(err); | 49 gFailures.push_back(err); |
| 50 } | 50 } |
| 51 | 51 |
| 52 static int32_t gPending = 0; // Atomic. | 52 static int32_t gPending = 0; // Atomic. Total number of running and queued tas
ks. |
| 53 |
| 54 SK_DECLARE_STATIC_MUTEX(gRunningMutex); |
| 55 static SkTArray<SkString> gRunning; |
| 53 | 56 |
| 54 static void done(double ms, | 57 static void done(double ms, |
| 55 ImplicitString config, ImplicitString src, ImplicitString name, | 58 ImplicitString config, ImplicitString src, ImplicitString name, |
| 56 ImplicitString log) { | 59 ImplicitString note, ImplicitString log) { |
| 60 SkString id = SkStringPrintf("%s %s %s", config.c_str(), src.c_str(), name.c
_str()); |
| 61 { |
| 62 SkAutoMutexAcquire lock(gRunningMutex); |
| 63 for (int i = 0; i < gRunning.count(); i++) { |
| 64 if (gRunning[i] == id) { |
| 65 gRunning.removeShuffle(i); |
| 66 break; |
| 67 } |
| 68 } |
| 69 } |
| 70 if (!FLAGS_verbose) { |
| 71 note = ""; |
| 72 } |
| 57 if (!log.isEmpty()) { | 73 if (!log.isEmpty()) { |
| 58 log.prepend("\n"); | 74 log.prepend("\n"); |
| 59 } | 75 } |
| 60 auto pending = sk_atomic_dec(&gPending)-1; | 76 auto pending = sk_atomic_dec(&gPending)-1; |
| 61 SkDebugf("%s(%4dMB %5d) %s\t%s %s %s%s", FLAGS_verbose ? "\n" : kSkOverwrite
Line | 77 SkDebugf("%s(%4dMB %5d) %s\t%s%s%s", FLAGS_verbose ? "\n" : kSkOverwriteLine |
| 62 , sk_tools::getBestResidentSetSizeMB(
) | 78 , sk_tools::getBestResidentSetSizeMB() |
| 63 , pending | 79 , pending |
| 64 , HumanizeMs(ms).c_str() | 80 , HumanizeMs(ms).c_str() |
| 65 , config.c_str() | 81 , id.c_str() |
| 66 , src.c_str() | 82 , note.c_str() |
| 67 , name.c_str() | 83 , log.c_str()); |
| 68 , log.c_str()); | |
| 69 // We write our dm.json file every once in a while in case we crash. | 84 // We write our dm.json file every once in a while in case we crash. |
| 70 // Notice this also handles the final dm.json when pending == 0. | 85 // Notice this also handles the final dm.json when pending == 0. |
| 71 if (pending % 500 == 0) { | 86 if (pending % 500 == 0) { |
| 72 JsonWriter::DumpJson(); | 87 JsonWriter::DumpJson(); |
| 73 } | 88 } |
| 74 } | 89 } |
| 75 | 90 |
| 91 static void start(ImplicitString config, ImplicitString src, ImplicitString name
) { |
| 92 SkString id = SkStringPrintf("%s %s %s", config.c_str(), src.c_str(), name.c
_str()); |
| 93 SkAutoMutexAcquire lock(gRunningMutex); |
| 94 gRunning.push_back(id); |
| 95 } |
| 96 |
| 76 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 97 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 77 | 98 |
| 78 struct Gold : public SkString { | 99 struct Gold : public SkString { |
| 79 Gold() : SkString("") {} | 100 Gold() : SkString("") {} |
| 80 Gold(ImplicitString sink, ImplicitString src, ImplicitString name, ImplicitS
tring md5) | 101 Gold(ImplicitString sink, ImplicitString src, ImplicitString name, ImplicitS
tring md5) |
| 81 : SkString("") { | 102 : SkString("") { |
| 82 this->append(sink); | 103 this->append(sink); |
| 83 this->append(src); | 104 this->append(src); |
| 84 this->append(name); | 105 this->append(name); |
| 85 this->append(md5); | 106 this->append(md5); |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 | 332 |
| 312 // The finest-grained unit of work we can run: draw a single Src into a single S
ink, | 333 // The finest-grained unit of work we can run: draw a single Src into a single S
ink, |
| 313 // report any errors, and perhaps write out the output: a .png of the bitmap, or
a raw stream. | 334 // report any errors, and perhaps write out the output: a .png of the bitmap, or
a raw stream. |
| 314 struct Task { | 335 struct Task { |
| 315 Task(const Tagged<Src>& src, const Tagged<Sink>& sink) : src(src), sink(sink
) {} | 336 Task(const Tagged<Src>& src, const Tagged<Sink>& sink) : src(src), sink(sink
) {} |
| 316 const Tagged<Src>& src; | 337 const Tagged<Src>& src; |
| 317 const Tagged<Sink>& sink; | 338 const Tagged<Sink>& sink; |
| 318 | 339 |
| 319 static void Run(Task* task) { | 340 static void Run(Task* task) { |
| 320 SkString name = task->src->name(); | 341 SkString name = task->src->name(); |
| 342 SkString note; |
| 321 SkString whyBlacklisted = is_blacklisted(task->sink.tag, task->src.tag,
name.c_str()); | 343 SkString whyBlacklisted = is_blacklisted(task->sink.tag, task->src.tag,
name.c_str()); |
| 344 if (!whyBlacklisted.isEmpty()) { |
| 345 note.appendf(" (--blacklist %s)", whyBlacklisted.c_str()); |
| 346 } |
| 322 SkString log; | 347 SkString log; |
| 323 WallTimer timer; | 348 WallTimer timer; |
| 324 timer.start(); | 349 timer.start(); |
| 325 if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) { | 350 if (!FLAGS_dryRun && whyBlacklisted.isEmpty()) { |
| 326 SkBitmap bitmap; | 351 SkBitmap bitmap; |
| 327 SkDynamicMemoryWStream stream; | 352 SkDynamicMemoryWStream stream; |
| 353 start(task->sink.tag, task->src.tag, name.c_str()); |
| 328 Error err = task->sink->draw(*task->src, &bitmap, &stream, &log); | 354 Error err = task->sink->draw(*task->src, &bitmap, &stream, &log); |
| 329 if (!err.isEmpty()) { | 355 if (!err.isEmpty()) { |
| 330 timer.end(); | 356 timer.end(); |
| 331 if (err.isFatal()) { | 357 if (err.isFatal()) { |
| 332 fail(SkStringPrintf("%s %s %s: %s", | 358 fail(SkStringPrintf("%s %s %s: %s", |
| 333 task->sink.tag, | 359 task->sink.tag, |
| 334 task->src.tag, | 360 task->src.tag, |
| 335 name.c_str(), | 361 name.c_str(), |
| 336 err.c_str())); | 362 err.c_str())); |
| 337 } else if (FLAGS_verbose) { | 363 } else { |
| 338 name.appendf(" (skipped: %s)", err.c_str()); | 364 note.appendf(" (skipped: %s)", err.c_str()); |
| 339 } | 365 } |
| 340 done(timer.fWall, task->sink.tag, task->src.tag, name, log); | 366 done(timer.fWall, task->sink.tag, task->src.tag, name, note, log
); |
| 341 return; | 367 return; |
| 342 } | 368 } |
| 343 SkAutoTDelete<SkStreamAsset> data(stream.detachAsStream()); | 369 SkAutoTDelete<SkStreamAsset> data(stream.detachAsStream()); |
| 344 | 370 |
| 345 SkString md5; | 371 SkString md5; |
| 346 if (!FLAGS_writePath.isEmpty() || !FLAGS_readPath.isEmpty()) { | 372 if (!FLAGS_writePath.isEmpty() || !FLAGS_readPath.isEmpty()) { |
| 347 SkMD5 hash; | 373 SkMD5 hash; |
| 348 if (data->getLength()) { | 374 if (data->getLength()) { |
| 349 hash.writeStream(data, data->getLength()); | 375 hash.writeStream(data, data->getLength()); |
| 350 data->rewind(); | 376 data->rewind(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 372 const char* ext = task->sink->fileExtension(); | 398 const char* ext = task->sink->fileExtension(); |
| 373 if (data->getLength()) { | 399 if (data->getLength()) { |
| 374 WriteToDisk(*task, md5, ext, data, data->getLength(), NULL); | 400 WriteToDisk(*task, md5, ext, data, data->getLength(), NULL); |
| 375 SkASSERT(bitmap.drawsNothing()); | 401 SkASSERT(bitmap.drawsNothing()); |
| 376 } else if (!bitmap.drawsNothing()) { | 402 } else if (!bitmap.drawsNothing()) { |
| 377 WriteToDisk(*task, md5, ext, NULL, 0, &bitmap); | 403 WriteToDisk(*task, md5, ext, NULL, 0, &bitmap); |
| 378 } | 404 } |
| 379 } | 405 } |
| 380 } | 406 } |
| 381 timer.end(); | 407 timer.end(); |
| 382 if (FLAGS_verbose && !whyBlacklisted.isEmpty()) { | 408 done(timer.fWall, task->sink.tag, task->src.tag, name, note, log); |
| 383 name.appendf(" (--blacklist, %s)", whyBlacklisted.c_str()); | |
| 384 } | |
| 385 done(timer.fWall, task->sink.tag, task->src.tag, name, log); | |
| 386 } | 409 } |
| 387 | 410 |
| 388 static void WriteToDisk(const Task& task, | 411 static void WriteToDisk(const Task& task, |
| 389 SkString md5, | 412 SkString md5, |
| 390 const char* ext, | 413 const char* ext, |
| 391 SkStream* data, size_t len, | 414 SkStream* data, size_t len, |
| 392 const SkBitmap* bitmap) { | 415 const SkBitmap* bitmap) { |
| 393 JsonWriter::BitmapResult result; | 416 JsonWriter::BitmapResult result; |
| 394 result.name = task.src->name(); | 417 result.name = task.src->name(); |
| 395 result.config = task.sink.tag; | 418 result.config = task.sink.tag; |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 JsonWriter::AddTestFailure(failure); | 515 JsonWriter::AddTestFailure(failure); |
| 493 } | 516 } |
| 494 bool allowExtendedTest() const SK_OVERRIDE { | 517 bool allowExtendedTest() const SK_OVERRIDE { |
| 495 return FLAGS_pathOpsExtended; | 518 return FLAGS_pathOpsExtended; |
| 496 } | 519 } |
| 497 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } | 520 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } |
| 498 } reporter; | 521 } reporter; |
| 499 WallTimer timer; | 522 WallTimer timer; |
| 500 timer.start(); | 523 timer.start(); |
| 501 if (!FLAGS_dryRun) { | 524 if (!FLAGS_dryRun) { |
| 525 start("unit", "test", test->name); |
| 502 GrContextFactory factory; | 526 GrContextFactory factory; |
| 503 test->proc(&reporter, &factory); | 527 test->proc(&reporter, &factory); |
| 504 } | 528 } |
| 505 timer.end(); | 529 timer.end(); |
| 506 done(timer.fWall, "unit", "test", test->name, ""); | 530 done(timer.fWall, "unit", "test", test->name, "", ""); |
| 507 } | 531 } |
| 508 | 532 |
| 509 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 533 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 510 | 534 |
| 511 // If we're isolating all GPU-bound work to one thread (the default), this funct
ion runs all that. | 535 // If we're isolating all GPU-bound work to one thread (the default), this funct
ion runs all that. |
| 512 static void run_enclave_and_gpu_tests(SkTArray<Task>* tasks) { | 536 static void run_enclave_and_gpu_tests(SkTArray<Task>* tasks) { |
| 513 run_enclave(tasks); | 537 run_enclave(tasks); |
| 514 for (int i = 0; i < gGPUTests.count(); i++) { | 538 for (int i = 0; i < gGPUTests.count(); i++) { |
| 515 run_test(&gGPUTests[i]); | 539 run_test(&gGPUTests[i]); |
| 516 } | 540 } |
| 517 } | 541 } |
| 518 | 542 |
| 519 // Some runs (mostly, Valgrind) are so slow that the bot framework thinks we've
hung. | 543 // Some runs (mostly, Valgrind) are so slow that the bot framework thinks we've
hung. |
| 520 // This prints something every once in a while so that it knows we're still work
ing. | 544 // This prints something every once in a while so that it knows we're still work
ing. |
| 521 static void start_keepalive() { | 545 static void start_keepalive() { |
| 522 struct Loop { | 546 struct Loop { |
| 523 static void forever(void*) { | 547 static void forever(void*) { |
| 524 for (;;) { | 548 for (;;) { |
| 525 static const int kSec = 300; | 549 static const int kSec = 300; |
| 526 #if defined(SK_BUILD_FOR_WIN) | 550 #if defined(SK_BUILD_FOR_WIN) |
| 527 Sleep(kSec * 1000); | 551 Sleep(kSec * 1000); |
| 528 #else | 552 #else |
| 529 sleep(kSec); | 553 sleep(kSec); |
| 530 #endif | 554 #endif |
| 531 SkDebugf("\nStill alive: doing science, reticulating splines...\
n"); | 555 SkString running; |
| 556 { |
| 557 SkAutoMutexAcquire lock(gRunningMutex); |
| 558 for (int i = 0; i < gRunning.count(); i++) { |
| 559 running.appendf("\n\t%s", gRunning[i].c_str()); |
| 560 } |
| 561 } |
| 562 SkDebugf("\nCurrently running:%s\n", running.c_str()); |
| 532 } | 563 } |
| 533 } | 564 } |
| 534 }; | 565 }; |
| 535 static SkThread* intentionallyLeaked = new SkThread(Loop::forever); | 566 static SkThread* intentionallyLeaked = new SkThread(Loop::forever); |
| 536 intentionallyLeaked->start(); | 567 intentionallyLeaked->start(); |
| 537 } | 568 } |
| 538 | 569 |
| 539 int dm_main(); | 570 int dm_main(); |
| 540 int dm_main() { | 571 int dm_main() { |
| 541 SetupCrashHandler(); | 572 SetupCrashHandler(); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 } | 632 } |
| 602 return 0; | 633 return 0; |
| 603 } | 634 } |
| 604 | 635 |
| 605 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 636 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
| 606 int main(int argc, char** argv) { | 637 int main(int argc, char** argv) { |
| 607 SkCommandLineFlags::Parse(argc, argv); | 638 SkCommandLineFlags::Parse(argc, argv); |
| 608 return dm_main(); | 639 return dm_main(); |
| 609 } | 640 } |
| 610 #endif | 641 #endif |
| OLD | NEW |