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 test->proc(&reporter, GetThreadLocalGrContextFactory()); |
393 } | 393 } |
394 timer.end(); | 394 timer.end(); |
395 done(timer.fWall, "unit", "test", test->name); | 395 done(timer.fWall, "unit", "test", test->name); |
396 } | 396 } |
397 | 397 |
398 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 398 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
399 | 399 |
400 // If we're isolating all GPU-bound work to one thread (the default), this funct ion runs all that. | |
401 static void run_enclave_and_gpu_tests(SkTArray<Task>* tasks) { | |
402 run_enclave(tasks); | |
403 for (int i = 0; i < gGPUTests.count(); i++) { | |
404 run_test(&gGPUTests[i]); | |
405 } | |
406 } | |
407 | |
400 int dm_main(); | 408 int dm_main(); |
401 int dm_main() { | 409 int dm_main() { |
402 SetupCrashHandler(); | 410 SetupCrashHandler(); |
403 SkAutoGraphics ag; | 411 SkAutoGraphics ag; |
404 SkTaskGroup::Enabler enabled(FLAGS_threads); | 412 SkTaskGroup::Enabler enabled(FLAGS_threads); |
405 | 413 |
406 gather_srcs(); | 414 gather_srcs(); |
407 gather_sinks(); | 415 gather_sinks(); |
408 gather_tests(); | 416 gather_tests(); |
409 | 417 |
410 gPending = gSrcs.count() * gSinks.count() + gCPUTests.count() + gGPUTests.co unt(); | 418 gPending = gSrcs.count() * gSinks.count() + gThreadedTests.count() + gGPUTes ts.count(); |
411 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", | 419 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", |
412 gSrcs.count(), gSinks.count(), gCPUTests.count() + gGPUTests.count( ), gPending); | 420 gSrcs.count(), gSinks.count(), gThreadedTests.count() + gGPUTests.c ount(), gPending); |
413 | 421 |
414 // We try to exploit as much parallelism as is safe. Most Src/Sink pairs ru n on any thread, | 422 // 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. | 423 // 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. | 424 // CPU tests run on any thread. GPU tests depend on --gpu_threading. |
417 SkTArray<Task> enclaves[kNumEnclaves]; | 425 SkTArray<Task> enclaves[kNumEnclaves]; |
418 for (int j = 0; j < gSinks.count(); j++) { | 426 for (int j = 0; j < gSinks.count(); j++) { |
419 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; | 427 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; |
420 for (int i = 0; i < gSrcs.count(); i++) { | 428 for (int i = 0; i < gSrcs.count(); i++) { |
421 tasks.push_back(Task(gSrcs[i], gSinks[j])); | 429 tasks.push_back(Task(gSrcs[i], gSinks[j])); |
422 } | 430 } |
423 } | 431 } |
424 | 432 |
425 SK_COMPILE_ASSERT(kAnyThread_Enclave == 0, AnyThreadZero); | |
426 SkTaskGroup tg; | 433 SkTaskGroup tg; |
427 tg.batch( Task::Run, enclaves[0].begin(), enclaves[0].count()); | 434 tg.batch(run_test, gThreadedTests.begin(), gThreadedTests.count()); |
428 tg.batch(run_enclave, enclaves+1, kNumEnclaves-1); | 435 for (int i = 0; i < kNumEnclaves; i++) { |
429 tg.batch( run_test, gCPUTests.begin(), gCPUTests.count()); | 436 switch(i) { |
430 if (FLAGS_gpu_threading) { | 437 case kAnyThread_Enclave: |
431 tg.batch(run_test, gGPUTests.begin(), gGPUTests.count()); | 438 tg.batch(Task::Run, enclaves[i].begin(), enclaves[i].count()); |
432 #if !defined(SK_BUILD_FOR_WIN32) | 439 break; |
433 } else { | 440 case kGPU_Enclave: |
434 for (int i = 0; i < gGPUTests.count(); i++) { | 441 tg.add(run_enclave_and_gpu_tests, &enclaves[i]); |
435 run_test(&gGPUTests[i]); | 442 break; |
436 } | 443 default: |
437 #endif | 444 tg.add(run_enclave, &enclaves[i]); |
445 break; | |
hal.canary
2015/01/21 22:23:31
What's wrong with
tg.batch(Task::Run,
| |
438 } | 446 } |
447 } | |
439 tg.wait(); | 448 tg.wait(); |
440 // At this point we're back in single-threaded land. | 449 // At this point we're back in single-threaded land. |
441 | 450 |
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"); | 451 SkDebugf("\n"); |
451 JsonWriter::DumpJson(); | 452 JsonWriter::DumpJson(); |
452 | 453 |
453 if (gFailures.count() > 0) { | 454 if (gFailures.count() > 0) { |
454 SkDebugf("Failures:\n"); | 455 SkDebugf("Failures:\n"); |
455 for (int i = 0; i < gFailures.count(); i++) { | 456 for (int i = 0; i < gFailures.count(); i++) { |
456 SkDebugf("\t%s\n", gFailures[i].c_str()); | 457 SkDebugf("\t%s\n", gFailures[i].c_str()); |
457 } | 458 } |
458 SkDebugf("%d failures\n", gFailures.count()); | 459 SkDebugf("%d failures\n", gFailures.count()); |
459 return 1; | 460 return 1; |
460 } | 461 } |
461 if (gPending > 0) { | 462 if (gPending > 0) { |
462 SkDebugf("Hrm, we didn't seem to run everything we intended to! Please file a bug.\n"); | 463 SkDebugf("Hrm, we didn't seem to run everything we intended to! Please file a bug.\n"); |
463 return 1; | 464 return 1; |
464 } | 465 } |
465 return 0; | 466 return 0; |
466 } | 467 } |
467 | 468 |
468 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 469 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
469 int main(int argc, char** argv) { | 470 int main(int argc, char** argv) { |
470 SkCommandLineFlags::Parse(argc, argv); | 471 SkCommandLineFlags::Parse(argc, argv); |
471 return dm_main(); | 472 return dm_main(); |
472 } | 473 } |
473 #endif | 474 #endif |
OLD | NEW |