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 "OverwriteLine.h" | 4 #include "OverwriteLine.h" |
5 #include "ProcStats.h" | 5 #include "ProcStats.h" |
6 #include "SkBBHFactory.h" | 6 #include "SkBBHFactory.h" |
7 #include "SkCommonFlags.h" | 7 #include "SkCommonFlags.h" |
8 #include "SkForceLinking.h" | 8 #include "SkForceLinking.h" |
9 #include "SkGraphics.h" | 9 #include "SkGraphics.h" |
10 #include "SkMD5.h" | 10 #include "SkMD5.h" |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 static void run_enclave(SkTArray<Task>* tasks) { | 346 static void run_enclave(SkTArray<Task>* tasks) { |
347 for (int i = 0; i < tasks->count(); i++) { | 347 for (int i = 0; i < tasks->count(); i++) { |
348 Task::Run(tasks->begin() + i); | 348 Task::Run(tasks->begin() + i); |
349 } | 349 } |
350 } | 350 } |
351 | 351 |
352 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 352 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
353 | 353 |
354 // Unit tests don't fit so well into the Src/Sink model, so we give them special
treatment. | 354 // Unit tests don't fit so well into the Src/Sink model, so we give them special
treatment. |
355 | 355 |
356 static SkTDArray<skiatest::Test> gCPUTests, gGPUTests; | 356 static SkTDArray<skiatest::Test> gThreadedTests, gGPUTests; |
357 | 357 |
358 static void gather_tests() { | 358 static void gather_tests() { |
359 if (!FLAGS_src.contains("tests")) { | 359 if (!FLAGS_src.contains("tests")) { |
360 return; | 360 return; |
361 } | 361 } |
362 for (const skiatest::TestRegistry* r = skiatest::TestRegistry::Head(); r; | 362 for (const skiatest::TestRegistry* r = skiatest::TestRegistry::Head(); r; |
363 r = r->next()) { | 363 r = r->next()) { |
364 // Despite its name, factory() is returning a reference to | 364 // Despite its name, factory() is returning a reference to |
365 // link-time static const POD data. | 365 // link-time static const POD data. |
366 const skiatest::Test& test = r->factory(); | 366 const skiatest::Test& test = r->factory(); |
367 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test.name)) { | 367 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test.name)) { |
368 continue; | 368 continue; |
369 } | 369 } |
370 if (test.needsGpu && gpu_supported()) { | 370 if (test.needsGpu && gpu_supported()) { |
371 gGPUTests.push(test); | 371 (FLAGS_gpu_threading ? gThreadedTests : gGPUTests).push(test); |
372 } else if (!test.needsGpu && FLAGS_cpu) { | 372 } else if (!test.needsGpu && FLAGS_cpu) { |
373 gCPUTests.push(test); | 373 gThreadedTests.push(test); |
374 } | 374 } |
375 } | 375 } |
376 } | 376 } |
377 | 377 |
378 static void run_test(skiatest::Test* test) { | 378 static void run_test(skiatest::Test* test) { |
379 struct : public skiatest::Reporter { | 379 struct : public skiatest::Reporter { |
380 void reportFailed(const skiatest::Failure& failure) SK_OVERRIDE { | 380 void reportFailed(const skiatest::Failure& failure) SK_OVERRIDE { |
381 fail(failure.toString()); | 381 fail(failure.toString()); |
382 JsonWriter::AddTestFailure(failure); | 382 JsonWriter::AddTestFailure(failure); |
383 } | 383 } |
384 bool allowExtendedTest() const SK_OVERRIDE { | 384 bool allowExtendedTest() const SK_OVERRIDE { |
385 return FLAGS_pathOpsExtended; | 385 return FLAGS_pathOpsExtended; |
386 } | 386 } |
387 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } | 387 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } |
388 } reporter; | 388 } reporter; |
389 WallTimer timer; | 389 WallTimer timer; |
390 timer.start(); | 390 timer.start(); |
391 if (!FLAGS_dryRun) { | 391 if (!FLAGS_dryRun) { |
392 test->proc(&reporter, GetThreadLocalGrContextFactory()); | 392 GrContextFactory factory; |
| 393 test->proc(&reporter, &factory); |
393 } | 394 } |
394 timer.end(); | 395 timer.end(); |
395 done(timer.fWall, "unit", "test", test->name); | 396 done(timer.fWall, "unit", "test", test->name); |
396 } | 397 } |
397 | 398 |
398 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 399 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
399 | 400 |
| 401 // If we're isolating all GPU-bound work to one thread (the default), this funct
ion runs all that. |
| 402 static void run_enclave_and_gpu_tests(SkTArray<Task>* tasks) { |
| 403 run_enclave(tasks); |
| 404 for (int i = 0; i < gGPUTests.count(); i++) { |
| 405 run_test(&gGPUTests[i]); |
| 406 } |
| 407 } |
| 408 |
400 int dm_main(); | 409 int dm_main(); |
401 int dm_main() { | 410 int dm_main() { |
402 SetupCrashHandler(); | 411 SetupCrashHandler(); |
403 SkAutoGraphics ag; | 412 SkAutoGraphics ag; |
404 SkTaskGroup::Enabler enabled(FLAGS_threads); | 413 SkTaskGroup::Enabler enabled(FLAGS_threads); |
405 | 414 |
406 gather_srcs(); | 415 gather_srcs(); |
407 gather_sinks(); | 416 gather_sinks(); |
408 gather_tests(); | 417 gather_tests(); |
409 | 418 |
410 gPending = gSrcs.count() * gSinks.count() + gCPUTests.count() + gGPUTests.co
unt(); | 419 gPending = gSrcs.count() * gSinks.count() + gThreadedTests.count() + gGPUTes
ts.count(); |
411 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", | 420 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", |
412 gSrcs.count(), gSinks.count(), gCPUTests.count() + gGPUTests.count(
), gPending); | 421 gSrcs.count(), gSinks.count(), gThreadedTests.count() + gGPUTests.c
ount(), gPending); |
413 | 422 |
414 // We try to exploit as much parallelism as is safe. Most Src/Sink pairs ru
n on any thread, | 423 // We try to exploit as much parallelism as is safe. Most Src/Sink pairs ru
n on any thread, |
415 // but Sinks that identify as part of a particular enclave run serially on a
single thread. | 424 // but Sinks that identify as part of a particular enclave run serially on a
single thread. |
416 // CPU tests run on any thread. GPU tests depend on --gpu_threading. | 425 // CPU tests run on any thread. GPU tests depend on --gpu_threading. |
417 SkTArray<Task> enclaves[kNumEnclaves]; | 426 SkTArray<Task> enclaves[kNumEnclaves]; |
418 for (int j = 0; j < gSinks.count(); j++) { | 427 for (int j = 0; j < gSinks.count(); j++) { |
419 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; | 428 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; |
420 for (int i = 0; i < gSrcs.count(); i++) { | 429 for (int i = 0; i < gSrcs.count(); i++) { |
421 tasks.push_back(Task(gSrcs[i], gSinks[j])); | 430 tasks.push_back(Task(gSrcs[i], gSinks[j])); |
422 } | 431 } |
423 } | 432 } |
424 | 433 |
425 SK_COMPILE_ASSERT(kAnyThread_Enclave == 0, AnyThreadZero); | |
426 SkTaskGroup tg; | 434 SkTaskGroup tg; |
427 tg.batch( Task::Run, enclaves[0].begin(), enclaves[0].count()); | 435 tg.batch(run_test, gThreadedTests.begin(), gThreadedTests.count()); |
428 tg.batch(run_enclave, enclaves+1, kNumEnclaves-1); | 436 for (int i = 0; i < kNumEnclaves; i++) { |
429 tg.batch( run_test, gCPUTests.begin(), gCPUTests.count()); | 437 switch(i) { |
430 if (FLAGS_gpu_threading) { | 438 case kAnyThread_Enclave: |
431 tg.batch(run_test, gGPUTests.begin(), gGPUTests.count()); | 439 tg.batch(Task::Run, enclaves[i].begin(), enclaves[i].count()); |
432 #if !defined(SK_BUILD_FOR_WIN32) | 440 break; |
433 } else { | 441 case kGPU_Enclave: |
434 for (int i = 0; i < gGPUTests.count(); i++) { | 442 tg.add(run_enclave_and_gpu_tests, &enclaves[i]); |
435 run_test(&gGPUTests[i]); | 443 break; |
436 } | 444 default: |
437 #endif | 445 tg.add(run_enclave, &enclaves[i]); |
| 446 break; |
438 } | 447 } |
| 448 } |
439 tg.wait(); | 449 tg.wait(); |
440 // At this point we're back in single-threaded land. | 450 // At this point we're back in single-threaded land. |
441 | 451 |
442 // This is not ideal for parallelism, but Windows seems crash-prone if we ru
n | |
443 // these GPU tests in parallel with any GPU Src/Sink work. Everyone else se
ems fine. | |
444 #if defined(SK_BUILD_FOR_WIN32) | |
445 for (int i = 0; i < gGPUTests.count(); i++) { | |
446 run_test(&gGPUTests[i]); | |
447 } | |
448 #endif | |
449 | |
450 SkDebugf("\n"); | 452 SkDebugf("\n"); |
451 JsonWriter::DumpJson(); | 453 JsonWriter::DumpJson(); |
452 | 454 |
453 if (gFailures.count() > 0) { | 455 if (gFailures.count() > 0) { |
454 SkDebugf("Failures:\n"); | 456 SkDebugf("Failures:\n"); |
455 for (int i = 0; i < gFailures.count(); i++) { | 457 for (int i = 0; i < gFailures.count(); i++) { |
456 SkDebugf("\t%s\n", gFailures[i].c_str()); | 458 SkDebugf("\t%s\n", gFailures[i].c_str()); |
457 } | 459 } |
458 SkDebugf("%d failures\n", gFailures.count()); | 460 SkDebugf("%d failures\n", gFailures.count()); |
459 return 1; | 461 return 1; |
460 } | 462 } |
461 if (gPending > 0) { | 463 if (gPending > 0) { |
462 SkDebugf("Hrm, we didn't seem to run everything we intended to! Please
file a bug.\n"); | 464 SkDebugf("Hrm, we didn't seem to run everything we intended to! Please
file a bug.\n"); |
463 return 1; | 465 return 1; |
464 } | 466 } |
465 return 0; | 467 return 0; |
466 } | 468 } |
467 | 469 |
468 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 470 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
469 int main(int argc, char** argv) { | 471 int main(int argc, char** argv) { |
470 SkCommandLineFlags::Parse(argc, argv); | 472 SkCommandLineFlags::Parse(argc, argv); |
471 return dm_main(); | 473 return dm_main(); |
472 } | 474 } |
473 #endif | 475 #endif |
OLD | NEW |