| 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" |
| 11 #include "SkOSFile.h" | 11 #include "SkOSFile.h" |
| 12 #include "SkTaskGroup.h" | 12 #include "SkTaskGroup.h" |
| 13 #include "Test.h" | 13 #include "Test.h" |
| 14 #include "Timer.h" | 14 #include "Timer.h" |
| 15 | 15 |
| 16 DEFINE_bool(tests, true, "Run tests?"); | 16 DEFINE_bool(tests, true, "Run tests?"); |
| 17 DEFINE_string(images, "resources", "Images to decode."); | 17 DEFINE_string(images, "resources", "Images to decode."); |
| 18 //DEFINE_string(src, "gm skp image subset", "Source types to test."); | 18 //DEFINE_string(src, "gm skp image subset", "Source types to test."); |
| 19 DEFINE_string(src, "gm skp", "Source types to test. TEMPORARILY DISABLED"); | 19 DEFINE_string(src, "gm skp", "Source types to test. TEMPORARILY DISABLED"); |
| 20 DEFINE_bool(nameByHash, false, | 20 DEFINE_bool(nameByHash, false, |
| 21 "If true, write to FLAGS_writePath[0]/<hash>.png instead of " | 21 "If true, write to FLAGS_writePath[0]/<hash>.png instead of " |
| 22 "to FLAGS_writePath[0]/<config>/<sourceType>/<name>.png"); | 22 "to FLAGS_writePath[0]/<config>/<sourceType>/<name>.png"); |
| 23 DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests."); | 23 DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests."); |
| 24 DEFINE_string(matrix, "1 0 0 0 1 0 0 0 1", | 24 DEFINE_string(matrix, "1 0 0 0 1 0 0 0 1", |
| 25 "Matrix to apply when using 'matrix' in config."); | 25 "Matrix to apply when using 'matrix' in config."); |
| 26 DEFINE_bool(gpu_threading, false, "Allow GPU work to run on multiple threads?"); |
| 26 | 27 |
| 27 __SK_FORCE_IMAGE_DECODER_LINKING; | 28 __SK_FORCE_IMAGE_DECODER_LINKING; |
| 28 using namespace DM; | 29 using namespace DM; |
| 29 | 30 |
| 30 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 31 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 31 | 32 |
| 32 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); | 33 SK_DECLARE_STATIC_MUTEX(gFailuresMutex); |
| 33 static SkTArray<SkString> gFailures; | 34 static SkTArray<SkString> gFailures; |
| 34 | 35 |
| 35 static void fail(ImplicitString err) { | 36 static void fail(ImplicitString err) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 #if SK_SUPPORT_GPU | 132 #if SK_SUPPORT_GPU |
| 132 return FLAGS_gpu; | 133 return FLAGS_gpu; |
| 133 #else | 134 #else |
| 134 return false; | 135 return false; |
| 135 #endif | 136 #endif |
| 136 } | 137 } |
| 137 | 138 |
| 138 static Sink* create_sink(const char* tag) { | 139 static Sink* create_sink(const char* tag) { |
| 139 #define SINK(t, sink, ...) if (0 == strcmp(t, tag)) { return new sink(__VA_ARGS_
_); } | 140 #define SINK(t, sink, ...) if (0 == strcmp(t, tag)) { return new sink(__VA_ARGS_
_); } |
| 140 if (gpu_supported()) { | 141 if (gpu_supported()) { |
| 142 typedef GrContextFactory Gr; |
| 141 const GrGLStandard api = get_gpu_api(); | 143 const GrGLStandard api = get_gpu_api(); |
| 142 SINK("gpunull", GPUSink, GrContextFactory::kNull_GLContextType, api
, 0, false); | 144 SINK("gpunull", GPUSink, Gr::kNull_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
| 143 SINK("gpudebug", GPUSink, GrContextFactory::kDebug_GLContextType, api
, 0, false); | 145 SINK("gpudebug", GPUSink, Gr::kDebug_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
| 144 SINK("gpu", GPUSink, GrContextFactory::kNative_GLContextType, api
, 0, false); | 146 SINK("gpu", GPUSink, Gr::kNative_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
| 145 SINK("gpudft", GPUSink, GrContextFactory::kNative_GLContextType, api
, 0, true); | 147 SINK("gpudft", GPUSink, Gr::kNative_GLContextType, api, 0, true, F
LAGS_gpu_threading); |
| 146 SINK("msaa4", GPUSink, GrContextFactory::kNative_GLContextType, api
, 4, false); | 148 SINK("msaa4", GPUSink, Gr::kNative_GLContextType, api, 4, false, F
LAGS_gpu_threading); |
| 147 SINK("msaa16", GPUSink, GrContextFactory::kNative_GLContextType, api
, 16, false); | 149 SINK("msaa16", GPUSink, Gr::kNative_GLContextType, api, 16, false, F
LAGS_gpu_threading); |
| 148 SINK("nvprmsaa4", GPUSink, GrContextFactory::kNVPR_GLContextType, api
, 4, false); | 150 SINK("nvprmsaa4", GPUSink, Gr::kNVPR_GLContextType, api, 4, false, F
LAGS_gpu_threading); |
| 149 SINK("nvprmsaa16", GPUSink, GrContextFactory::kNVPR_GLContextType, api
, 16, false); | 151 SINK("nvprmsaa16", GPUSink, Gr::kNVPR_GLContextType, api, 16, false, F
LAGS_gpu_threading); |
| 150 #if SK_ANGLE | 152 #if SK_ANGLE |
| 151 SINK("angle", GPUSink, GrContextFactory::kANGLE_GLContextType, api
, 0, false); | 153 SINK("angle", GPUSink, Gr::kANGLE_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
| 152 #endif | 154 #endif |
| 153 #if SK_MESA | 155 #if SK_MESA |
| 154 SINK("mesa", GPUSink, GrContextFactory::kMESA_GLContextType, api
, 0, false); | 156 SINK("mesa", GPUSink, Gr::kMESA_GLContextType, api, 0, false, F
LAGS_gpu_threading); |
| 155 #endif | 157 #endif |
| 156 } | 158 } |
| 157 | 159 |
| 158 if (FLAGS_cpu) { | 160 if (FLAGS_cpu) { |
| 159 SINK("565", RasterSink, kRGB_565_SkColorType); | 161 SINK("565", RasterSink, kRGB_565_SkColorType); |
| 160 SINK("8888", RasterSink, kN32_SkColorType); | 162 SINK("8888", RasterSink, kN32_SkColorType); |
| 161 // TODO(mtklein): reenable once skiagold can handle .pdf uploads. | 163 // TODO(mtklein): reenable once skiagold can handle .pdf uploads. |
| 162 //SINK("pdf", PDFSink); | 164 //SINK("pdf", PDFSink); |
| 163 } | 165 } |
| 164 #undef SINK | 166 #undef SINK |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 void onReportFailed(const skiatest::Failure& failure) SK_OVERRIDE { | 340 void onReportFailed(const skiatest::Failure& failure) SK_OVERRIDE { |
| 339 SkString s; | 341 SkString s; |
| 340 failure.getFailureString(&s); | 342 failure.getFailureString(&s); |
| 341 fail(s); | 343 fail(s); |
| 342 JsonWriter::AddTestFailure(failure); | 344 JsonWriter::AddTestFailure(failure); |
| 343 } | 345 } |
| 344 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_pathOpsExtended; } | 346 bool allowExtendedTest() const SK_OVERRIDE { return FLAGS_pathOpsExtended; } |
| 345 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } | 347 bool verbose() const SK_OVERRIDE { return FLAGS_veryVerbose; } |
| 346 } gTestReporter; | 348 } gTestReporter; |
| 347 | 349 |
| 348 static SkTArray<SkAutoTDelete<skiatest::Test>, kMemcpyOK> gTests; | 350 static SkTArray<SkAutoTDelete<skiatest::Test>, kMemcpyOK> gCPUTests, gGPUTests; |
| 349 | 351 |
| 350 static void gather_tests() { | 352 static void gather_tests() { |
| 351 if (!FLAGS_tests) { | 353 if (!FLAGS_tests) { |
| 352 return; | 354 return; |
| 353 } | 355 } |
| 354 for (const skiatest::TestRegistry* r = skiatest::TestRegistry::Head(); r; r
= r->next()) { | 356 for (const skiatest::TestRegistry* r = skiatest::TestRegistry::Head(); r; r
= r->next()) { |
| 355 SkAutoTDelete<skiatest::Test> test(r->factory()(NULL)); | 357 SkAutoTDelete<skiatest::Test> test(r->factory()(NULL)); |
| 356 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) { | 358 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) { |
| 357 continue; | 359 continue; |
| 358 } | 360 } |
| 359 if (test->isGPUTest() /*&& !gpu_supported()*/) { // TEMPORARILY DISABLE
D | 361 |
| 360 continue; | 362 test->setReporter(&gTestReporter); |
| 363 if (test->isGPUTest() && gpu_supported()) { |
| 364 gGPUTests.push_back().reset(test.detach()); |
| 365 } else if (!test->isGPUTest() && FLAGS_cpu) { |
| 366 gCPUTests.push_back().reset(test.detach()); |
| 361 } | 367 } |
| 362 if (!test->isGPUTest() && !FLAGS_cpu) { | |
| 363 continue; | |
| 364 } | |
| 365 test->setReporter(&gTestReporter); | |
| 366 gTests.push_back().reset(test.detach()); | |
| 367 } | 368 } |
| 368 } | 369 } |
| 369 | 370 |
| 370 static void run_test(SkAutoTDelete<skiatest::Test>* t) { | 371 static void run_test(SkAutoTDelete<skiatest::Test>* t) { |
| 371 WallTimer timer; | 372 WallTimer timer; |
| 372 timer.start(); | 373 timer.start(); |
| 373 skiatest::Test* test = t->get(); | 374 skiatest::Test* test = t->get(); |
| 374 if (!FLAGS_dryRun) { | 375 if (!FLAGS_dryRun) { |
| 375 GrContextFactory grFactory; | 376 test->setGrContextFactory(GetThreadLocalGrContextFactory()); |
| 376 test->setGrContextFactory(&grFactory); | |
| 377 test->run(); | 377 test->run(); |
| 378 if (!test->passed()) { | 378 if (!test->passed()) { |
| 379 fail(SkStringPrintf("test %s failed", test->getName())); | 379 fail(SkStringPrintf("test %s failed", test->getName())); |
| 380 } | 380 } |
| 381 } | 381 } |
| 382 timer.end(); | 382 timer.end(); |
| 383 done(timer.fWall, "unit", "test", test->getName()); | 383 done(timer.fWall, "unit", "test", test->getName()); |
| 384 } | 384 } |
| 385 | 385 |
| 386 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 386 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 387 | 387 |
| 388 int dm_main(); | 388 int dm_main(); |
| 389 int dm_main() { | 389 int dm_main() { |
| 390 SetupCrashHandler(); | 390 SetupCrashHandler(); |
| 391 SkAutoGraphics ag; | 391 SkAutoGraphics ag; |
| 392 SkTaskGroup::Enabler enabled(FLAGS_threads); | 392 SkTaskGroup::Enabler enabled(FLAGS_threads); |
| 393 | 393 |
| 394 gather_srcs(); | 394 gather_srcs(); |
| 395 gather_sinks(); | 395 gather_sinks(); |
| 396 gather_tests(); | 396 gather_tests(); |
| 397 | 397 |
| 398 gPending = gSrcs.count() * gSinks.count() + gTests.count(); | 398 gPending = gSrcs.count() * gSinks.count() + gCPUTests.count() + gGPUTests.co
unt(); |
| 399 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", | 399 SkDebugf("%d srcs * %d sinks + %d tests == %d tasks\n", |
| 400 gSrcs.count(), gSinks.count(), gTests.count(), gPending); | 400 gSrcs.count(), gSinks.count(), gCPUTests.count() + gGPUTests.count(
), gPending); |
| 401 | 401 |
| 402 // We try to exploit as much parallelism as is safe. Most Src/Sink pairs ru
n on any thread, | 402 // We try to exploit as much parallelism as is safe. Most Src/Sink pairs ru
n on any thread, |
| 403 // but Sinks that identify as part of a particular enclave run serially on a
single thread. | 403 // but Sinks that identify as part of a particular enclave run serially on a
single thread. |
| 404 // Tests run on any thread, with a separate GrContextFactory for each GPU te
st. | 404 // CPU tests run on any thread. GPU tests depend on --gpu_threading. |
| 405 SkTArray<Task> enclaves[kNumEnclaves]; | 405 SkTArray<Task> enclaves[kNumEnclaves]; |
| 406 for (int j = 0; j < gSinks.count(); j++) { | 406 for (int j = 0; j < gSinks.count(); j++) { |
| 407 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; | 407 SkTArray<Task>& tasks = enclaves[gSinks[j]->enclave()]; |
| 408 for (int i = 0; i < gSrcs.count(); i++) { | 408 for (int i = 0; i < gSrcs.count(); i++) { |
| 409 tasks.push_back(Task(gSrcs[i], gSinks[j])); | 409 tasks.push_back(Task(gSrcs[i], gSinks[j])); |
| 410 } | 410 } |
| 411 } | 411 } |
| 412 | 412 |
| 413 SK_COMPILE_ASSERT(kAnyThread_Enclave == 0, AnyThreadZero); | 413 SK_COMPILE_ASSERT(kAnyThread_Enclave == 0, AnyThreadZero); |
| 414 SkTaskGroup tg; | 414 SkTaskGroup tg; |
| 415 tg.batch( Task::Run, enclaves[0].begin(), enclaves[0].count()); | 415 tg.batch( Task::Run, enclaves[0].begin(), enclaves[0].count()); |
| 416 tg.batch(run_enclave, enclaves+1, kNumEnclaves-1); | 416 tg.batch(run_enclave, enclaves+1, kNumEnclaves-1); |
| 417 tg.batch( run_test, gTests.begin(), gTests.count()); | 417 tg.batch( run_test, gCPUTests.begin(), gCPUTests.count()); |
| 418 if (FLAGS_gpu_threading) { |
| 419 tg.batch(run_test, gGPUTests.begin(), gGPUTests.count()); |
| 420 } else { |
| 421 for (int i = 0; i < gGPUTests.count(); i++) { |
| 422 run_test(&gGPUTests[i]); |
| 423 } |
| 424 } |
| 418 tg.wait(); | 425 tg.wait(); |
| 419 | 426 |
| 420 // At this point we're back in single-threaded land. | 427 // At this point we're back in single-threaded land. |
| 421 | 428 |
| 422 if (!FLAGS_verbose) { | 429 if (!FLAGS_verbose) { |
| 423 SkDebugf("\n"); | 430 SkDebugf("\n"); |
| 424 } | 431 } |
| 425 | 432 |
| 426 JsonWriter::DumpJson(); | 433 JsonWriter::DumpJson(); |
| 427 | 434 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 439 } | 446 } |
| 440 return 0; | 447 return 0; |
| 441 } | 448 } |
| 442 | 449 |
| 443 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 450 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
| 444 int main(int argc, char** argv) { | 451 int main(int argc, char** argv) { |
| 445 SkCommandLineFlags::Parse(argc, argv); | 452 SkCommandLineFlags::Parse(argc, argv); |
| 446 return dm_main(); | 453 return dm_main(); |
| 447 } | 454 } |
| 448 #endif | 455 #endif |
| OLD | NEW |