diff options
author | caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-11-01 17:36:03 +0000 |
---|---|---|
committer | caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-11-01 17:36:03 +0000 |
commit | a2bbc6e19d5332e81784e582c290cc060f40c4c7 (patch) | |
tree | 507a82e41b5a59f261295718091f0f1491b3d894 /tests | |
parent | 045c3d330c6c14f090c2222ece08d82cb84fb3ea (diff) |
pathops work in progress
BUG=
Review URL: https://codereview.chromium.org/52653002
git-svn-id: http://skia.googlecode.com/svn/trunk@12089 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tests')
-rw-r--r-- | tests/PathOpsCubicIntersectionTest.cpp | 12 | ||||
-rw-r--r-- | tests/PathOpsCubicLineIntersectionTest.cpp | 3 | ||||
-rw-r--r-- | tests/PathOpsCubicQuadIntersectionTest.cpp | 24 | ||||
-rw-r--r-- | tests/PathOpsDQuadTest.cpp | 15 | ||||
-rw-r--r-- | tests/PathOpsDTriangleTest.cpp | 30 | ||||
-rw-r--r-- | tests/PathOpsExtendedTest.cpp | 5 | ||||
-rw-r--r-- | tests/PathOpsOpTest.cpp | 36 | ||||
-rw-r--r-- | tests/PathOpsQuadIntersectionTest.cpp | 3 | ||||
-rw-r--r-- | tests/PathOpsQuadLineIntersectionTest.cpp | 7 | ||||
-rwxr-xr-x | tests/PathOpsSkpClipTest.cpp | 807 | ||||
-rwxr-xr-x | tests/PathOpsSkpTest.cpp | 924 | ||||
-rw-r--r-- | tests/PathOpsThreadedCommon.h | 9 | ||||
-rwxr-xr-x | tests/PathOpsTypesTest.cpp | 24 | ||||
-rwxr-xr-x | tests/SkpSkGrTest.cpp | 759 |
14 files changed, 2437 insertions, 221 deletions
diff --git a/tests/PathOpsCubicIntersectionTest.cpp b/tests/PathOpsCubicIntersectionTest.cpp index 04797b4ef3..c8a2e05e66 100644 --- a/tests/PathOpsCubicIntersectionTest.cpp +++ b/tests/PathOpsCubicIntersectionTest.cpp @@ -164,11 +164,23 @@ static const SkDCubic testSet[] = { const size_t testSetCount = SK_ARRAY_COUNT(testSet); static const SkDCubic newTestSet[] = { +{{{275,532}, {277.209137,532}, {279,530.209106}, {279,528}}}, +{{{278,529}, {278,530.65686}, {276.65686,532}, {275,532}}}, + #if 0 // FIXME: asserts coincidence, not working yet {{{195, 785}, {124.30755615234375, 785}, {67, 841.85986328125}, {67, 912}}}, {{{67, 913}, {67, 842.30755615234375}, {123.85984039306641, 785}, {194, 785}}}, #endif +{{{149,710.001465}, {149.000809,712.209961}, {150.791367,714}, {153,714}}}, +{{{154,715}, {151.238571,715}, {149,712.761414}, {149,710}}}, + +{{{1,2}, {1,2}, {2,0}, {6,0}}}, +{{{0,2}, {0,6}, {2,1}, {2,1}}}, + +{{{0,1}, {2,3}, {5,1}, {4,3}}}, +{{{1,5}, {3,4}, {1,0}, {3,2}}}, + {{{399,657}, {399,661.970581}, {403.029449,666}, {408,666}}}, {{{406,666}, {402.686279,666}, {400,663.313721}, {400,660}}}, diff --git a/tests/PathOpsCubicLineIntersectionTest.cpp b/tests/PathOpsCubicLineIntersectionTest.cpp index 49219fbfe5..53e9d60d88 100644 --- a/tests/PathOpsCubicLineIntersectionTest.cpp +++ b/tests/PathOpsCubicLineIntersectionTest.cpp @@ -15,6 +15,9 @@ static struct lineCubic { SkDCubic cubic; SkDLine line; } lineCubicTests[] = { + {{{{154,715}, {151.238571,715}, {149,712.761414}, {149,710}}}, + {{{149,675}, {149,710.001465}}}}, + {{{{0,1}, {1,6}, {4,1}, {4,3}}}, {{{6,1}, {1,4}}}}, diff --git a/tests/PathOpsCubicQuadIntersectionTest.cpp b/tests/PathOpsCubicQuadIntersectionTest.cpp index c9da2c7378..35b49d2351 100644 --- a/tests/PathOpsCubicQuadIntersectionTest.cpp +++ b/tests/PathOpsCubicQuadIntersectionTest.cpp @@ -17,14 +17,32 @@ static struct lineCubic { int answerCount; SkDPoint answers[2]; } quadCubicTests[] = { + {{{{778, 14089}, {778, 14091.208984375}, {776.20916748046875, 14093}, {774, 14093}}},
+ {{{778, 14089}, {777.99957275390625, 14090.65625}, {776.82843017578125, 14091.828125}}}, 2,
+ {{778, 14089}, {776.82855609581270,14091.828250841330}}},
+ + {{{{1110, 817}, {1110.55225f, 817}, {1111, 817.447693f}, {1111, 818}}}, + {{{1110.70715f, 817.292908f}, {1110.41406f, 817.000122f}, {1110, 817}}}, 2, + {{1110, 817}, {1110.70715f, 817.292908f}}}, + + {{{{1110, 817}, {1110.55225f, 817}, {1111, 817.447693f}, {1111, 818}}}, + {{{1111, 818}, {1110.99988f, 817.585876f}, {1110.70715f, 817.292908f}}}, 2, + {{1110.70715f, 817.292908f}, {1111, 818}}}, + + {{{{55, 207}, {52.238574981689453, 207}, {50, 204.76142883300781}, {50, 202}}}, + {{{55, 207}, {52.929431915283203, 206.99949645996094}, + {51.464466094970703, 205.53553771972656}}}, 2, + {{55, 207}, {51.464466094970703, 205.53553771972656}}}, + {{{{49, 47}, {49, 74.614250183105469}, {26.614250183105469, 97}, {-1, 97}}}, {{{-8.659739592076221e-015, 96.991401672363281}, {20.065492630004883, 96.645187377929688}, {34.355339050292969, 82.355339050292969}}}, 2, - {{34.355339050292969,82.355339050292969}, {34.306797674910243,82.403823585863449}}}, + {{34.355339050292969,82.355339050292969}, {34.28654835573549, 82.424006509351585}}}, {{{{10,234}, {10,229.58172607421875}, {13.581720352172852,226}, {18,226}}}, {{{18,226}, {14.686291694641113,226}, {12.342399597167969,228.3424072265625}}}, 1, {{18,226}, {0,0}}}, + {{{{10,234}, {10,229.58172607421875}, {13.581720352172852,226}, {18,226}}}, {{{12.342399597167969,228.3424072265625}, {10,230.68629455566406}, {10,234}}}, 1, {{10,234}, {0,0}}}, @@ -69,6 +87,10 @@ static void PathOpsCubicQuadIntersectionTest(skiatest::Reporter* reporter) { for (int idx2 = 0; idx2 < quadCubicTests[index].answerCount; ++idx2) { found |= quadCubicTests[index].answers[idx2].approximatelyEqual(xy1); } + if (!found) { + SkDebugf("%s [%d,%d] xy1=(%g,%g) != \n", + __FUNCTION__, iIndex, pt, xy1.fX, xy1.fY); + } REPORTER_ASSERT(reporter, found); } reporter->bumpTestCount(); diff --git a/tests/PathOpsDQuadTest.cpp b/tests/PathOpsDQuadTest.cpp index 5921b69578..e6f1deb72f 100644 --- a/tests/PathOpsDQuadTest.cpp +++ b/tests/PathOpsDQuadTest.cpp @@ -5,7 +5,9 @@ * found in the LICENSE file. */ #include "PathOpsTestCommon.h" +#include "SkPath.h" #include "SkPathOpsQuad.h" +#include "SkRRect.h" #include "Test.h" static const SkDQuad tests[] = { @@ -21,7 +23,7 @@ static const SkDPoint inPoint[]= { {1, 0.8}, {1.8, 1}, {1.5, 1}, - {0.5, 0.5}, + {0.4999, 0.5}, // was 0.5, 0.5; points on the hull are considered outside }; static const SkDPoint outPoint[]= { @@ -51,5 +53,16 @@ static void PathOpsDQuadTest(skiatest::Reporter* reporter) { } } +static void PathOpsRRectTest(skiatest::Reporter* reporter) { + SkPath path; + SkRRect rRect; + SkRect rect = {135, 143, 250, 177}; + SkVector radii[4] = {{8, 8}, {8, 8}, {0, 0}, {0, 0}}; + rRect.setRectRadii(rect, radii); + path.addRRect(rRect); +} + #include "TestClassDef.h" DEFINE_TESTCLASS_SHORT(PathOpsDQuadTest) + +DEFINE_TESTCLASS_SHORT(PathOpsRRectTest) diff --git a/tests/PathOpsDTriangleTest.cpp b/tests/PathOpsDTriangleTest.cpp index 35bfe06b88..6aec3086bb 100644 --- a/tests/PathOpsDTriangleTest.cpp +++ b/tests/PathOpsDTriangleTest.cpp @@ -45,5 +45,31 @@ static void PathOpsTriangleUtilitiesTest(skiatest::Reporter* reporter) { } } -#include "TestClassDef.h" -DEFINE_TESTCLASS_SHORT(PathOpsTriangleUtilitiesTest) +static const SkDTriangle oneOff[] = {
+ {{{271.03291625750461, 5.0402503630087025e-05}, {275.21652430019037, 3.6997300650817753},
+ {279.25839233398438, 7.7416000366210938}}},
+
+ {{{271.03291625750461, 5.0402503617874572e-05}, {275.21652430019037, 3.6997300650817877},
+ {279.25839233398438, 7.7416000366210938}}}
+};
+
+static const size_t oneOff_count = SK_ARRAY_COUNT(oneOff);
+
+static void PathOpsTriangleOneOffTest(skiatest::Reporter* reporter) {
+ for (size_t index = 0; index < oneOff_count; ++index) {
+ const SkDTriangle& triangle = oneOff[index];
+ SkASSERT(ValidTriangle(triangle));
+ for (int inner = 0; inner < 3; ++inner) {
+ bool result = triangle.contains(triangle.fPts[inner]);
+ if (result) {
+ SkDebugf("%s [%d][%d] point on triangle is not in\n", __FUNCTION__, index, inner);
+ REPORTER_ASSERT(reporter, 0);
+ }
+ }
+ }
+}
+
+#include "TestClassDef.h"
+DEFINE_TESTCLASS_SHORT(PathOpsTriangleUtilitiesTest)
+
+DEFINE_TESTCLASS_SHORT(PathOpsTriangleOneOffTest)
diff --git a/tests/PathOpsExtendedTest.cpp b/tests/PathOpsExtendedTest.cpp index 28830ed702..ca6f86507d 100644 --- a/tests/PathOpsExtendedTest.cpp +++ b/tests/PathOpsExtendedTest.cpp @@ -12,6 +12,7 @@ #include "SkForceLinking.h" #include "SkMatrix.h" #include "SkPaint.h" +#include "SkRTConf.h" #include "SkStream.h" #include "SkThreadPool.h" @@ -634,6 +635,10 @@ bool testThreadedPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP SK_DECLARE_STATIC_MUTEX(gMutex); int initializeTests(skiatest::Reporter* reporter, const char* test) { +#if 0 // doesn't work yet + SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true); + SK_CONF_SET("images.png.suppressDecoderWarnings", true); +#endif #ifdef SK_DEBUG SkPathOpsDebug::gMaxWindSum = 4; SkPathOpsDebug::gMaxWindValue = 4; diff --git a/tests/PathOpsOpTest.cpp b/tests/PathOpsOpTest.cpp index 08ae1b939d..d192e0b359 100644 --- a/tests/PathOpsOpTest.cpp +++ b/tests/PathOpsOpTest.cpp @@ -2718,8 +2718,6 @@ static void skpakmmos_ru100(skiatest::Reporter* reporter) { testPathOp(reporter, path, pathB, kIntersect_PathOp); } -#define SKPS_WORKING 0 -#if SKPS_WORKING static void skpcarpetplanet_ru22(skiatest::Reporter* reporter) { SkPath path; path.setFillType(SkPath::kEvenOdd_FillType); @@ -2744,6 +2742,8 @@ static void skpcarpetplanet_ru22(skiatest::Reporter* reporter) { testPathOp(reporter, path, pathB, kIntersect_PathOp); } +#define SKPS_WORKING 0 +#if SKPS_WORKING static void skpcarrot_is24(skiatest::Reporter* reporter) { SkPath path; path.setFillType(SkPath::kEvenOdd_FillType); @@ -3010,7 +3010,33 @@ static void cubicOp96d(skiatest::Reporter* reporter) { testPathOp(reporter, path, pathB, kDifference_PathOp); } -static void (*firstTest)(skiatest::Reporter* ) = 0; +static void cubicOp97x(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 2);
+ path.cubicTo(0, 6, 2, 1, 2, 1);
+ path.close();
+ pathB.setFillType(SkPath::kEvenOdd_FillType);
+ pathB.moveTo(1, 2);
+ pathB.cubicTo(1, 2, 2, 0, 6, 0);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kXOR_PathOp);
+} + +static void cubicOp98x(skiatest::Reporter* reporter) {
+ SkPath path, pathB;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(0, 3);
+ path.cubicTo(3, 6, 4, 1, 6, 3);
+ path.close();
+ pathB.setFillType(SkPath::kEvenOdd_FillType);
+ pathB.moveTo(1, 4);
+ pathB.cubicTo(3, 6, 3, 0, 6, 3);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kXOR_PathOp);
+} + +static void (*firstTest)(skiatest::Reporter* ) = bufferOverflow; static struct TestDesc tests[] = { #if ISSUE_1435_WORKING @@ -3018,11 +3044,13 @@ static struct TestDesc tests[] = { #endif #if SKPS_WORKING TEST(skpcarrot_is24), - TEST(skpcarpetplanet_ru22), // cubic/cubic intersect detects unwanted coincidence #endif #if ISSUE_1417_WORKING_ON_LINUX_32 TEST(issue1417), #endif + TEST(cubicOp98x), + TEST(cubicOp97x), + TEST(skpcarpetplanet_ru22), // cubic/cubic intersect detects unwanted coincidence TEST(cubicOp96d), TEST(cubicOp95u), TEST(skpadbox_lt15), diff --git a/tests/PathOpsQuadIntersectionTest.cpp b/tests/PathOpsQuadIntersectionTest.cpp index 07d2dac854..900123bbd2 100644 --- a/tests/PathOpsQuadIntersectionTest.cpp +++ b/tests/PathOpsQuadIntersectionTest.cpp @@ -53,6 +53,9 @@ static void standardTestCases(skiatest::Reporter* reporter) { } static const SkDQuad testSet[] = { +{{{164, -40}, {231.51681518554687, -40}, {279.25839233398438, 7.7416000366210938}}},
+{{{279.25839233398438, 7.7416000366210938}, {275.2164306640625, 3.6996400356292725}, {271.03286743164062, -5.3290705182007514e-015}}},
+ {{{2.9999997378517067, 1.9737872594345709}, {2.9999997432230918, 1.9739647181863822}, {1.2414155459263587e-163, 5.2957833941332142e-315}}}, {{{2.9999047485265304, 1.9739164225694723}, {3.0000947268526112, 1.9738379076623633}, {0.61149411077591886, 0.0028382324376270418}}}, diff --git a/tests/PathOpsQuadLineIntersectionTest.cpp b/tests/PathOpsQuadLineIntersectionTest.cpp index a871417f1f..4793a13a20 100644 --- a/tests/PathOpsQuadLineIntersectionTest.cpp +++ b/tests/PathOpsQuadLineIntersectionTest.cpp @@ -59,6 +59,9 @@ static struct oneLineQuad { SkDQuad quad; SkDLine line; } oneOffs[] = { + {{{{447.96701049804687, 894.4381103515625}, {448.007080078125, 894.4239501953125},
+ {448.0140380859375, 894.4215087890625}}},
+ {{{490.43548583984375, 879.40740966796875}, {405.59262084960937, 909.435546875}}}}, {{{{142.589081, 102.283646}, {149.821579, 100}, {158, 100}}}, {{{90, 230}, {160, 60}}}}, {{{{1101, 10}, {1101, 8.3431453704833984}, {1099.828857421875, 7.1711997985839844}}}, @@ -94,7 +97,7 @@ static void testOneOffs(skiatest::Reporter* reporter) { } } -static void PathOpsQuadLineIntersectionTestOne(skiatest::Reporter* reporter) { +static void PathOpsQuadLineIntersectionOneOffTest(skiatest::Reporter* reporter) { testOneOffs(reporter); } @@ -148,4 +151,4 @@ static void PathOpsQuadLineIntersectionTest(skiatest::Reporter* reporter) { #include "TestClassDef.h" DEFINE_TESTCLASS_SHORT(PathOpsQuadLineIntersectionTest) -DEFINE_TESTCLASS_SHORT(PathOpsQuadLineIntersectionTestOne) +DEFINE_TESTCLASS_SHORT(PathOpsQuadLineIntersectionOneOffTest) diff --git a/tests/PathOpsSkpClipTest.cpp b/tests/PathOpsSkpClipTest.cpp index d2fa988c6c..7905faa9a5 100755 --- a/tests/PathOpsSkpClipTest.cpp +++ b/tests/PathOpsSkpClipTest.cpp @@ -1,207 +1,573 @@ -#include "PathOpsExtendedTest.h" -#include "PathOpsThreadedCommon.h" + #include "SkBitmap.h" +#include "SkCanvas.h" #include "SkColor.h" +#include "SkColorPriv.h" #include "SkDevice.h" -#include "SkCanvas.h" +#include "SkGraphics.h" #include "SkImageDecoder.h" #include "SkImageEncoder.h" -#include "SkStream.h" #include "SkOSFile.h" +#include "SkPathOpsDebug.h" #include "SkPicture.h" +#include "SkRTConf.h" +#include "SkStream.h" #include "SkString.h" +#include "SkTArray.h" +#include "SkTDArray.h" +#include "SkThreadPool.h" +#include "SkTime.h" +#include "Test.h" #ifdef SK_BUILD_FOR_WIN #define PATH_SLASH "\\" - #define IN_DIR "D:" PATH_SLASH "skp" - #define OUT_DIR "D:" PATH_SLASH + #define IN_DIR "D:\\9-30-13\\" + #define OUT_DIR "D:\\opSkpClip\\1\\" #else #define PATH_SLASH "/" - #if 1 - #define IN_DIR "/usr/local/google/home/caryclark/new10k" PATH_SLASH - #define OUT_DIR "/usr/local/google/home/caryclark/out10k" PATH_SLASH + #ifdef SK_BUILD_FOR_MAC + #define IN_DIR "/Volumes/tera/9-30-13/skp" + #define OUT_DIR "/Volumes/tera/out/9-30-13/1/" #else - #define IN_DIR "/usr/local/google/home/caryclark/6-18-13" PATH_SLASH - #define OUT_DIR "/usr/local/google/home/caryclark" PATH_SLASH + #define IN_DIR "/usr/local/google/home/caryclark/skps/9-30-13/skp" + #define OUT_DIR "/mnt/skia/opSkpClip/1/" #endif #endif -static const char pictDir[] = IN_DIR ; -static const char outSkpClipDir[] = OUT_DIR "skpClip"; -static const char outOldClipDir[] = OUT_DIR "oldClip"; +const struct { + int directory; + const char* filename; +} skipOverSept[] = { + {9, "http___www_symptome_ch_.skp"}, // triangle clip with corner at x.999 + {11, "http___www_menly_fr_.skp"}, + {12, "http___www_banrasdr_com_.skp"}, +}; + +size_t skipOverSeptCount = sizeof(skipOverSept) / sizeof(skipOverSept[0]); + +enum TestStep { + kCompareBits, + kEncodeFiles, +}; + +enum { + kMaxLength = 128, + kMaxFiles = 128, + kSmallLimit = 1000, +}; + +struct TestResult { + void init(int dirNo) { + fDirNo = dirNo; + sk_bzero(fFilename, sizeof(fFilename)); + fTestStep = kCompareBits; + fScaleOversized = true; + } + + SkString status() { + SkString outStr; + outStr.printf("%s %d %d\n", fFilename, fPixelError, fTime); + return outStr; + } + + static void Test(int dirNo, const char* filename, TestStep testStep) { + TestResult test; + test.init(dirNo); + test.fTestStep = testStep; + strcpy(test.fFilename, filename); + test.testOne(); + } + + void test(int dirNo, const SkString& filename) { + init(dirNo); + strcpy(fFilename, filename.c_str()); + testOne(); + } + + void testOne(); + + char fFilename[kMaxLength]; + TestStep fTestStep; + int fDirNo; + int fPixelError; + int fTime; + bool fScaleOversized; +}; + +struct TestState { + void init(int dirNo, skiatest::Reporter* reporter) { + fReporter = reporter; + fResult.init(dirNo); + fFoundCount = 0; + TestState::fSmallCount = 0; + fSmallestError = 0; + sk_bzero(fFilesFound, sizeof(fFilesFound)); + sk_bzero(fDirsFound, sizeof(fDirsFound)); + sk_bzero(fError, sizeof(fError)); + } + + static bool bumpSmallCount() { + sk_atomic_inc(&fSmallCount); + return fSmallCount > kSmallLimit; + } + + static void clearSmallCount() { + if (fSmallCount < kSmallLimit) { + fSmallCount = 0; + } + } + + char fFilesFound[kMaxFiles][kMaxLength]; + int fDirsFound[kMaxFiles]; + int fError[kMaxFiles]; + int fFoundCount; + static int fSmallCount; + int fSmallestError; + skiatest::Reporter* fReporter; + TestResult fResult; +}; + +int TestState::fSmallCount; + +struct TestRunner { + TestRunner(skiatest::Reporter* reporter, int threadCount) + : fNumThreads(threadCount) + , fReporter(reporter) { + } + + ~TestRunner(); + void render(); + int fNumThreads; + SkTDArray<class TestRunnable*> fRunnables; + skiatest::Reporter* fReporter; +}; + +class TestRunnable : public SkRunnable { +public: + TestRunnable(void (*testFun)(TestState*), int dirNo, TestRunner* runner) { + fState.init(dirNo, runner->fReporter); + fTestFun = testFun; + } + + virtual void run() SK_OVERRIDE { + SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024); + (*fTestFun)(&fState); + } + + TestState fState; + void (*fTestFun)(TestState*); +}; + +TestRunner::~TestRunner() { + for (int index = 0; index < fRunnables.count(); index++) { + SkDELETE(fRunnables[index]); + } +} + +void TestRunner::render() { + SkThreadPool pool(fNumThreads); + for (int index = 0; index < fRunnables.count(); ++ index) { + pool.add(fRunnables[index]); + } +} + +//////////////////////////////////////////////// + +static const char outOpDir[] = OUT_DIR "opClip"; +static const char outOldDir[] = OUT_DIR "oldClip"; +static const char outSkpDir[] = OUT_DIR "skpTest"; +static const char outDiffDir[] = OUT_DIR "outTest"; +static const char outStatusDir[] = OUT_DIR "statusTest"; -static SkString make_filepath(const char* dir, const SkString& name) { +static SkString make_filepath(int dirNo, const char* dir, const char* name) { SkString path(dir); - size_t len = strlen(dir); - if (len > 0 && dir[len - 1] != PATH_SLASH[0]) { - path.append(PATH_SLASH); + if (dirNo) { + path.appendf("%d", dirNo); } + path.append(PATH_SLASH); path.append(name); return path; } -static SkString make_png_name(const SkString& filename) { +static SkString make_in_dir_name(int dirNo) { + SkString dirName(IN_DIR); + dirName.appendf("%d", dirNo); + if (!sk_exists(dirName.c_str())) { + SkDebugf("could not read dir %s\n", dirName.c_str()); + return SkString(); + } + return dirName; +} + +static bool make_one_out_dir(const char* outDirStr) { + SkString outDir = make_filepath(0, outDirStr, ""); + if (!sk_exists(outDir.c_str())) { + if (!sk_mkdir(outDir.c_str())) { + SkDebugf("could not create dir %s\n", outDir.c_str()); + return false; + } + } + return true; +} + +static bool make_out_dirs() { + SkString outDir = make_filepath(0, OUT_DIR, ""); + if (!sk_exists(outDir.c_str())) { + if (!sk_mkdir(outDir.c_str())) { + SkDebugf("could not create dir %s\n", outDir.c_str()); + return false; + } + } + return make_one_out_dir(outOldDir) + && make_one_out_dir(outOpDir) + && make_one_out_dir(outSkpDir) + && make_one_out_dir(outDiffDir) + && make_one_out_dir(outStatusDir); +} + +static SkString make_png_name(const char* filename) { SkString pngName = SkString(filename); pngName.remove(pngName.size() - 3, 3); pngName.append("png"); return pngName; } -static void testOne(const SkString& filename) { - if (filename == SkString("http___migracioncolombia_gov_co.skp") - || filename == SkString("http___miuki_info.skp") - ) { - return; +static int similarBits(const SkBitmap& gr, const SkBitmap& sk) { + const int kRowCount = 3; + const int kThreshold = 3; + int width = SkTMin(gr.width(), sk.width()); + if (width < kRowCount) { + return true; } -#if DEBUG_SHOW_TEST_NAME - SkString testName(filename); - const char http[] = "http"; - if (testName.startsWith(http)) { - testName.remove(0, sizeof(http) - 1); + int height = SkTMin(gr.height(), sk.height()); + if (height < kRowCount) { + return true; } - while (testName.startsWith("_")) { - testName.remove(0, 1); + int errorTotal = 0; + SkTArray<int, true> errorRows; + errorRows.push_back_n(width * kRowCount); + SkAutoLockPixels autoGr(gr); + SkAutoLockPixels autoSk(sk); + for (int y = 0; y < height; ++y) { + SkPMColor* grRow = gr.getAddr32(0, y); + SkPMColor* skRow = sk.getAddr32(0, y); + int* base = &errorRows[0]; + int* cOut = &errorRows[y % kRowCount]; + for (int x = 0; x < width; ++x) { + SkPMColor grColor = grRow[x]; + SkPMColor skColor = skRow[x]; + int dr = SkGetPackedR32(grColor) - SkGetPackedR32(skColor); + int dg = SkGetPackedG32(grColor) - SkGetPackedG32(skColor); + int db = SkGetPackedB32(grColor) - SkGetPackedB32(skColor); + int error = cOut[x] = SkTMax(SkAbs32(dr), SkTMax(SkAbs32(dg), SkAbs32(db))); + if (error < kThreshold || x < 2) { + continue; + } + if (base[x - 2] < kThreshold + || base[width + x - 2] < kThreshold + || base[width * 2 + x - 2] < kThreshold + || base[x - 1] < kThreshold + || base[width + x - 1] < kThreshold + || base[width * 2 + x - 1] < kThreshold + || base[x] < kThreshold + || base[width + x] < kThreshold + || base[width * 2 + x] < kThreshold) { + continue; + } + errorTotal += error; + } } - const char dotSkp[] = ".skp"; - if (testName.endsWith(dotSkp)) { - size_t len = testName.size(); - testName.remove(len - (sizeof(dotSkp) - 1), sizeof(dotSkp) - 1); + return errorTotal; +} + +static bool addError(TestState* data, const TestResult& testResult) { + bool foundSmaller = false; + int dCount = data->fFoundCount; + int pixelError = testResult.fPixelError; + if (data->fFoundCount < kMaxFiles) { + data->fError[dCount] = pixelError; + strcpy(data->fFilesFound[dCount], testResult.fFilename); + data->fDirsFound[dCount] = testResult.fDirNo; + ++data->fFoundCount; + } else if (pixelError > data->fSmallestError) { + int smallest = SK_MaxS32; + int smallestIndex = 0; + for (int index = 0; index < kMaxFiles; ++index) { + if (smallest > data->fError[index]) { + smallest = data->fError[index]; + smallestIndex = index; + } + } + data->fError[smallestIndex] = pixelError; + strcpy(data->fFilesFound[smallestIndex], testResult.fFilename); + data->fDirsFound[smallestIndex] = testResult.fDirNo; + data->fSmallestError = SK_MaxS32; + for (int index = 0; index < kMaxFiles; ++index) { + if (data->fSmallestError > data->fError[index]) { + data->fSmallestError = data->fError[index]; + } + } + SkDebugf("*%d*", data->fSmallestError); + foundSmaller = true; } - testName.prepend("skp"); - testName.append("1"); - strncpy(DEBUG_FILENAME_STRING, testName.c_str(), DEBUG_FILENAME_STRING_LENGTH); -#endif - SkString path = make_filepath(pictDir, filename); - SkFILEStream stream(path.c_str()); - if (!stream.isValid()) { - return; + return foundSmaller; +} + + + +static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) { + canvas->save(); + int pWidth = pic->width(); + int pHeight = pic->height(); + const int maxDimension = 1000; + const int slices = 3; + int xInterval = SkTMax(pWidth - maxDimension, 0) / (slices - 1); + int yInterval = SkTMax(pHeight - maxDimension, 0) / (slices - 1); + SkRect rect = {0, 0, SkIntToScalar(SkTMin(maxDimension, pWidth)), + SkIntToScalar(SkTMin(maxDimension, pHeight))}; + canvas->clipRect(rect); + SkMSec start = SkTime::GetMSecs(); + for (int x = 0; x < slices; ++x) { + for (int y = 0; y < slices; ++y) { + pic->draw(canvas); + canvas->translate(0, SkIntToScalar(yInterval)); + } + canvas->translate(SkIntToScalar(xInterval), SkIntToScalar(-yInterval * slices)); } - SkPicture* pic = SkPicture::CreateFromStream(&stream, &SkImageDecoder::DecodeMemory); - if (!pic) { - SkDebugf("unable to decode %s\n", filename.c_str()); - return; + SkMSec end = SkTime::GetMSecs(); + canvas->restore(); + return end - start; +} + +static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) { + canvas->clear(SK_ColorWHITE); + if (scale != 1) { + canvas->save(); + canvas->scale(1.0f / scale, 1.0f / scale); } - int width = pic->width(); - int height = pic->height(); - - SkBitmap bitmap; - int scale = 1; - do { - bitmap.setConfig(SkBitmap::kARGB_8888_Config, (width + scale - 1) / scale, - (height + scale - 1) / scale); - bool success = bitmap.allocPixels(); - bitmap.eraseColor(SK_ColorWHITE); - if (success) { - break; - } - SkDebugf("-%d-", scale); - } while ((scale *= 2) < 32); - if (scale >= 32) { - SkDebugf("unable to allocate bitmap for %s (w=%d h=%d)\n", filename.c_str(), - width, height); - return; + pic->draw(canvas); + if (scale != 1) { + canvas->restore(); + } +} + +static void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) { + SkString outFile = make_filepath(0, outDir, pngName); + if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, + SkImageEncoder::kPNG_Type, 100)) { + SkDebugf("unable to encode gr %s (width=%d height=%d)\n", pngName, + bitmap.width(), bitmap.height()); } - SkCanvas canvas(bitmap); - canvas.scale(1.0f / scale, 1.0f / scale); - SkString pngName = make_png_name(filename); - for (int i = 0; i < 2; ++i) { - bool useOp = i ? true : false; - canvas.setAllowSimplifyClip(useOp); - pic->draw(&canvas); - SkString outFile = make_filepath(useOp ? outSkpClipDir : outOldClipDir, pngName); - if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, SkImageEncoder::kPNG_Type, - 100)) { - SkDebugf("unable to encode %s (width=%d height=%d)\n", pngName.c_str(), - bitmap.width(), bitmap.height()); +} + +void TestResult::testOne() { + SkPicture* pic = NULL; + { + #if DEBUG_SHOW_TEST_NAME + if (fTestStep == kCompareBits) { + SkString testName(fFilename); + const char http[] = "http"; + if (testName.startsWith(http)) { + testName.remove(0, sizeof(http) - 1); + } + while (testName.startsWith("_")) { + testName.remove(0, 1); + } + const char dotSkp[] = ".skp"; + if (testName.endsWith(dotSkp)) { + size_t len = testName.size(); + testName.remove(len - (sizeof(dotSkp) - 1), sizeof(dotSkp) - 1); + } + testName.prepend("skp"); + testName.append("1"); + strncpy(DEBUG_FILENAME_STRING, testName.c_str(), DEBUG_FILENAME_STRING_LENGTH); + } else if (fTestStep == kEncodeFiles) { + strncpy(DEBUG_FILENAME_STRING, "", DEBUG_FILENAME_STRING_LENGTH); + } + #endif + SkString path = make_filepath(fDirNo, IN_DIR, fFilename); + SkFILEStream stream(path.c_str()); + if (!stream.isValid()) { + SkDebugf("invalid stream %s\n", path.c_str()); + goto finish; + } + SkPicture* pic = SkPicture::CreateFromStream(&stream, &SkImageDecoder::DecodeMemory); + if (!pic) { + SkDebugf("unable to decode %s\n", fFilename); + goto finish; + } + int width = pic->width(); + int height = pic->height(); + SkBitmap oldBitmap, opBitmap; + int scale = 1; + do { + int dimX = (width + scale - 1) / scale; + int dimY = (height + scale - 1) / scale; + oldBitmap.setConfig(SkBitmap::kARGB_8888_Config, dimX, dimY); + opBitmap.setConfig(SkBitmap::kARGB_8888_Config, dimX, dimY); + bool success = oldBitmap.allocPixels() && opBitmap.allocPixels(); + if (success) { + break; + } + SkDebugf("-%d-", scale); + } while ((scale *= 2) < 256); + if (scale >= 256) { + SkDebugf("unable to allocate bitmap for %s (w=%d h=%d)\n", fFilename, + width, height); + return; + } + oldBitmap.eraseColor(SK_ColorWHITE); + SkCanvas oldCanvas(oldBitmap); + oldCanvas.setAllowSimplifyClip(false); + opBitmap.eraseColor(SK_ColorWHITE); + SkCanvas opCanvas(opBitmap); + opCanvas.setAllowSimplifyClip(true); + drawPict(pic, &oldCanvas, fScaleOversized ? scale : 1); + drawPict(pic, &opCanvas, fScaleOversized ? scale : 1); + if (fTestStep == kCompareBits) { + fPixelError = similarBits(oldBitmap, opBitmap); + int oldTime = timePict(pic, &oldCanvas); + int opTime = timePict(pic, &opCanvas); + fTime = oldTime - opTime; + } else if (fTestStep == kEncodeFiles) { + SkString pngStr = make_png_name(fFilename); + const char* pngName = pngStr.c_str(); + writePict(oldBitmap, outOldDir, pngName); + writePict(opBitmap, outOpDir, pngName); } } +finish: SkDELETE(pic); } -const char* tryFixed[] = { - 0 -}; +static SkString makeStatusString(int dirNo) { + SkString statName; + statName.printf("stats%d.txt", dirNo); + SkString statusFile = make_filepath(0, outStatusDir, statName.c_str()); + return statusFile; +} -size_t tryFixedCount = sizeof(tryFixed) / sizeof(tryFixed[0]); - -const char* skipOver[] = { - "http___carpetplanet_ru.skp", // cubic/cubic intersect - "http___carrot_is.skp", // bridgeOp() SkASSERT(unsortable || !current->done()); - -/*!*/"http___dotsrc_org.skp", // asserts in png decode - "http___frauen_magazin_com.skp", // bridgeOp() SkASSERT(unsortable || !current->done()); - "http___i_gino_com.skp", // unexpected cubic/quad coincidence - // {61, 857, 61, 789.06897, 116.068977, 734, 184, 734} - // {184, 734, 133.051727, 734, 97.0258636, 770.025879} - "http___ilkoora_com.skp", // assert wind sum != min32 from markDoneBinary / findNextOp #28k -/*!*/"http___migracioncolombia_gov_co.skp", // crashes on picture decode - "http___mm4everfriends_com.skp", // bumpSpan/addTCoincident (from calcPartialCoincidentWinding) - "http___mtrk_uz.skp", // checkEnds() assert #36.3k - "http___pchappy_com_au.skp", // bridgeOp() assert unsortable || ! empty #37.2k - "http___sciality_com.skp", // bridgeOp() SkASSERT(unsortable || !current->done()); #32.4k -/*!*/"http___sozialticker_com.skp", // asserts in png decode - "http___sudoestenegocios_com.skp", // assert fT < 1 in addTCoincident - "http___thesuburbanite_com.skp", // bridgeOp() SkASSERT(unsortable || !current->done()); - - "http___fluentin3months_com.skp", // calcCommonCoincidentWinding from calcPartialCoincidentWinding #38.3k - "http___teachersbadi_blogspot_in.skp", // calcCommonCoincidentWinding from calcPartialCoincidentWinding #53.4k - "http___wsms_ru.skp", // assert wind sum != min32 from markDoneBinary / findNextOp #49.5k - "http___voycer_de.skp", // calcCommonCoincidentWinding from calcPartialCoincidentWinding #47k - "http___77hz_jp.skp", // addTCancel from calcCoincidentWinding #47.1k - - "http___hostloco_com.skp", // t < 0 AddIntersectsT -/*!*/"http___oggicronaca_it.skp", // asserts in png decode - "http___sergeychunkevich_com.skp", // t < 0 AddIntersectsT - "http___tracksflow_com.skp", // assert otherEnd >= 0 from nextChase - "http___autobutler_dk.skp", // t < 0 AddIntersectsT - "http___onlinecollege_org.skp", // bridgeOp() assert unsortable || ! empty #100.1k - "http___national_com_au.skp", // bridgeOp() assert unsortable || ! empty #110.2k -/*!*/"http___anitadongre_com.skp", // exceptionally large width and height - "http___rentacheat_com.skp", // bridgeOp() assert unsortable || ! empty #110.8k -/*!*/"http___gruesse_de.skp", // asserts in png decode -/*!*/"http___crn_in.png", // width=1250047 - "http___breakmystyle_com.skp", // assert qPt == lPt in quad intersection - "http___naoxrane_ru.skp", // assert t4+...t0 == 0 in quartic roots #128.3k - "http___tcmevents_org.skp", // assert in addTCoincident (from calcPartialCoincidentWinding) #143.3k -/*!*/"http___listbuildingcashsecrets_com.skp", // asserts in png decode #152.7k -/*!*/"http___skyscraperpage_com.skp", // asserts in png decode #155.5k - "http___mlk_com.skp", // bridgeOp() assert unsortable || ! empty #158.7k - "http___sd_graphic_net.skp", // bridgeOp() assert unsortable || ! empty #163.3k - "http___kopepasah_com.skp", // checkEnds() assert #188.2k -/*!*/"http___darkreloaded_com.skp", // asserts in png decode #188.4k - "http___redbullskatearcade_es.skp", // bridgeOp() assert unsortable || ! empty #192.5k - "http___partainasdemo250_org.skp", // bridgeOp() assert unsortable || ! empty #200.2k - -// these failures are from the new 10k set - "http___www_freerepublic_com_.skp", // assert in opangle < - "http___www_lavoixdunord_fr_.skp", // bridgeOp() assert unsortable || ! empty - "http___www_booking_com_.skp", // bridgeOp() assert unsortable || ! empty - "http___www_fj_p_com_.skp", // markWinding assert from findChaseOp - "http___www_leadpages_net_.skp", // assert in opangle < - "http___www_despegar_com_mx_.skp", // bridgeOp() assert unsortable || ! empty -}; +class PreParser { +public: + PreParser(int dirNo) + : fDirNo(dirNo) + , fIndex(0) { + SkString statusPath = makeStatusString(dirNo); + if (!sk_exists(statusPath.c_str())) { + return; + } + SkFILEStream reader; + reader.setPath(statusPath.c_str()); + while (fetch(reader, &fResults.push_back())) + ; + fResults.pop_back(); + } + + bool fetch(SkFILEStream& reader, TestResult* result) { + char c; + int i = 0; + result->init(fDirNo); + result->fPixelError = 0; + result->fTime = 0; + do { + bool readOne = reader.read(&c, 1) != 0; + if (!readOne) { + SkASSERT(i == 0); + return false; + } + if (c == ' ') { + result->fFilename[i++] = '\0'; + break; + } + result->fFilename[i++] = c; + SkASSERT(i < kMaxLength); + } while (true); + do { + SkAssertResult(reader.read(&c, 1)); + if (c == ' ') { + break; + } + SkASSERT(c >= '0' && c <= '9'); + result->fPixelError = result->fPixelError * 10 + (c - '0'); + } while (true); + bool minus = false; + do { + SkAssertResult(reader.read(&c, 1)); + if (c == '\n') { + break; + } + if (c == '-') { + minus = true; + continue; + } + SkASSERT(c >= '0' && c <= '9'); + result->fTime = result->fTime * 10 + (c - '0'); + } while (true); + if (minus) { + result->fTime = -result->fTime; + } + return true; + } -size_t skipOverCount = sizeof(skipOver) / sizeof(skipOver[0]); + bool match(const SkString& filename, SkFILEWStream* stream, TestResult* result) { + if (fIndex < fResults.count()) { + *result = fResults[fIndex++]; + SkASSERT(filename.equals(result->fFilename)); + SkString outStr(result->status()); + stream->write(outStr.c_str(), outStr.size()); + return true; + } + return false; + } -static void PathOpsSkpClipTest(skiatest::Reporter* reporter) { - SkOSFile::Iter iter(pictDir, "skp"); +private: + int fDirNo; + int fIndex; + SkTArray<TestResult, true> fResults; +}; + +static bool doOneDir(TestState* state) { + int dirNo = state->fResult.fDirNo; + skiatest::Reporter* reporter = state->fReporter; + SkString dirName = make_in_dir_name(dirNo); + SkASSERT(dirName.size()); + SkOSFile::Iter iter(dirName.c_str(), "skp"); SkString filename; int testCount = 0; + PreParser preParser(dirNo); + SkFILEWStream statusStream(makeStatusString(dirNo).c_str()); while (iter.next(&filename)) { - SkString pngName = make_png_name(filename); - SkString oldPng = make_filepath(outOldClipDir, pngName); - SkString newPng = make_filepath(outSkpClipDir, pngName); - if (sk_exists(oldPng.c_str()) && sk_exists(newPng.c_str())) { - reporter->bumpTestCount(); - continue; - } - for (size_t index = 0; index < skipOverCount; ++index) { - if (skipOver[index] && strcmp(filename.c_str(), skipOver[index]) == 0) { - reporter->bumpTestCount(); + for (size_t index = 0; index < skipOverSeptCount; ++index) { + if (skipOverSept[index].directory == dirNo + && strcmp(filename.c_str(), skipOverSept[index].filename) == 0) { goto skipOver; } } - testOne(filename); + if (preParser.match(filename, &statusStream, &state->fResult)) { + addError(state, state->fResult); + ++testCount; + goto checkEarlyExit; + } + if (state->fSmallestError > 5000000) { + return false; + } + { + TestResult& result = state->fResult; + result.test(dirNo, filename); + SkString outStr(result.status()); + statusStream.write(outStr.c_str(), outStr.size()); + statusStream.flush(); + if (1) { + SkDebugf("%s", outStr.c_str()); + } + bool noMatch = addError(state, state->fResult); + if (noMatch) { + state->clearSmallCount(); + } else if (state->bumpSmallCount()) { + return false; + } + } + ++testCount; if (reporter->verbose()) { SkDebugf("."); if (++testCount % 100 == 0) { @@ -209,85 +575,112 @@ static void PathOpsSkpClipTest(skiatest::Reporter* reporter) { } } skipOver: - reporter->bumpTestCount(); + if (reporter->verbose()) { + static int threadTestCount; + SkDebugf("."); + sk_atomic_inc(&threadTestCount); + if (threadTestCount % 100 == 0) { + SkDebugf("%d\n", threadTestCount); + } + } +checkEarlyExit: + if (1 && testCount == 20) { + return true; + } } + return true; +} + +static bool initTest() { +#if !defined SK_BUILD_FOR_WIN && !defined SK_BUILD_FOR_MAC + SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true); + SK_CONF_SET("images.png.suppressDecoderWarnings", true); +#endif + return make_out_dirs(); } -static void bumpCount(skiatest::Reporter* reporter, bool skipping) { +static void encodeFound(skiatest::Reporter* reporter, TestState& state) { if (reporter->verbose()) { - static int threadTestCount; - if (!skipping) { - SkDebugf("."); + for (int index = 0; index < state.fFoundCount; ++index) { + SkDebugf("%d %s %d\n", state.fDirsFound[index], state.fFilesFound[index], + state.fError[index]); } - sk_atomic_inc(&threadTestCount); - if (!skipping && threadTestCount % 100 == 0) { - SkDebugf("%d\n", threadTestCount); + } + for (int index = 0; index < state.fFoundCount; ++index) { + TestResult::Test(state.fDirsFound[index], state.fFilesFound[index], kEncodeFiles); + if (state.fReporter->verbose()) SkDebugf("+"); + } +} + +static void PathOpsSkpClipTest(skiatest::Reporter* reporter) { + if (!initTest()) { + return; + } + SkTArray<TestResult, true> errors; + TestState state; + state.init(0, reporter); + for (int dirNo = 1; dirNo <= 100; ++dirNo) { + if (reporter->verbose()) { + SkDebugf("dirNo=%d\n", dirNo); } - if (skipping && threadTestCount % 10000 == 0) { - SkDebugf("%d\n", threadTestCount); + state.fResult.fDirNo = dirNo; + if (!doOneDir(&state)) { + break; } } + encodeFound(reporter, state); } -static void testSkpClipMain(PathOpsThreadState* data) { - SkString str(data->fSerialNo); - testOne(str); - bumpCount(data->fReporter, false); - data->fReporter->bumpTestCount(); +static void testSkpClipMain(TestState* data) { + (void) doOneDir(data); } static void PathOpsSkpClipThreadedTest(skiatest::Reporter* reporter) { - int threadCount = initializeTests(reporter, "skpClipThreadedTest"); - PathOpsThreadedTestRunner testRunner(reporter, threadCount); - SkOSFile::Iter iter(pictDir, "skp"); - SkString filename; - while (iter.next(&filename)) { - SkString pngName = make_png_name(filename); - SkString oldPng = make_filepath(outOldClipDir, pngName); - SkString newPng = make_filepath(outSkpClipDir, pngName); - if (sk_exists(oldPng.c_str()) && sk_exists(newPng.c_str())) { - bumpCount(reporter, true); - continue; - } - for (size_t index = 0; index < skipOverCount; ++index) { - if (skipOver[index] && strcmp(filename.c_str(), skipOver[index]) == 0) { - bumpCount(reporter, true); - goto skipOver; - } - } - *testRunner.fRunnables.append() = SkNEW_ARGS(PathOpsThreadedRunnable, - (&testSkpClipMain, filename.c_str(), &testRunner)); -skipOver: - ; + if (!initTest()) { + return; + } + int threadCount = reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1; + TestRunner testRunner(reporter, threadCount); + for (int dirNo = 1; dirNo <= 100; ++dirNo) { + *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnable, + (&testSkpClipMain, dirNo, &testRunner)); } testRunner.render(); -} - -static void PathOpsSkpClipFixedTest(skiatest::Reporter* reporter) { - for (size_t index = 0; index < tryFixedCount; ) { - SkString filename(tryFixed[index]); - testOne(filename); - ++index; - if (reporter->verbose()) { - SkDebugf("."); - if (index % 100 == 0) { - SkDebugf("\n"); - } + TestState state; + state.init(0, reporter); + for (int dirNo = 1; dirNo <= 100; ++dirNo) { + TestState& testState = testRunner.fRunnables[dirNo - 1]->fState; + for (int inner = 0; inner < testState.fFoundCount; ++inner) { + TestResult& testResult = testState.fResult; + SkASSERT(testResult.fDirNo == dirNo); + testResult.fPixelError = testState.fError[inner]; + strcpy(testResult.fFilename, testState.fFilesFound[inner]); + addError(&state, testResult); } - reporter->bumpTestCount(); } + encodeFound(reporter, state); } static void PathOpsSkpClipOneOffTest(skiatest::Reporter* reporter) { - SkString filename("http___78_cn_.skp"); - testOne(filename); + if (!initTest()) { + return; + } + const int testIndex = 43 - 41; + int dirNo = skipOverSept[testIndex].directory; + SkAssertResult(make_in_dir_name(dirNo).size()); + SkString filename(skipOverSept[testIndex].filename); + TestResult state; + state.test(dirNo, filename); + if (reporter->verbose()) { + SkDebugf("%s", state.status().c_str()); + } + state.fTestStep = kEncodeFiles; + state.testOne(); } #include "TestClassDef.h" DEFINE_TESTCLASS_SHORT(PathOpsSkpClipTest) -DEFINE_TESTCLASS_SHORT(PathOpsSkpClipFixedTest) - DEFINE_TESTCLASS_SHORT(PathOpsSkpClipOneOffTest) DEFINE_TESTCLASS_SHORT(PathOpsSkpClipThreadedTest) diff --git a/tests/PathOpsSkpTest.cpp b/tests/PathOpsSkpTest.cpp index b0feff7ef1..7eb0a54ec3 100755 --- a/tests/PathOpsSkpTest.cpp +++ b/tests/PathOpsSkpTest.cpp @@ -508,8 +508,6 @@ static void skpmtrk_uz27(skiatest::Reporter* reporter) { testPathOp(reporter, path, pathB, kIntersect_PathOp); } -#define TRY_BROKEN_TESTS 0 -#if TRY_BROKEN_TESTS static void skpfrauen_magazin_com83(skiatest::Reporter* reporter) { SkPath path; path.setFillType(SkPath::kEvenOdd_FillType); @@ -534,6 +532,8 @@ static void skpfrauen_magazin_com83(skiatest::Reporter* reporter) { testPathOp(reporter, path, pathB, kIntersect_PathOp); } +#define TRY_BROKEN_TESTS 0 +#if TRY_BROKEN_TESTS static void skpi_gino_com16(skiatest::Reporter* reporter) { SkPath path; path.setFillType(SkPath::kEvenOdd_FillType); @@ -614,6 +614,7 @@ static void skpsciality_com161(skiatest::Reporter* reporter) { pathB.close(); testPathOp(reporter, path, pathB, kIntersect_PathOp); } +#endif static void skpsudoestenegocios_com186(skiatest::Reporter* reporter) { SkPath path; @@ -665,18 +666,933 @@ static void skpthesuburbanite_com213(skiatest::Reporter* reporter) { pathB.close(); testPathOp(reporter, path, pathB, kIntersect_PathOp); } + +static void skphostloco_com11(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(6.66133815e-16f, 648); + path.lineTo(25.8522835f, 648); + path.quadTo(27.5087376f, 647.999634f, 28.6807098f, 646.82843f); + path.quadTo(29.8518829f, 645.656433f, 29.8522835f, 644); + path.lineTo(29.8522835f, 467); + path.quadTo(29.8518829f, 465.343536f, 28.6807098f, 464.17157f); + path.quadTo(27.5087376f, 463.000397f, 25.8522835f, 463); + path.lineTo(2.22044605e-16f, 463); + path.lineTo(6.66133815e-16f, 648); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(0, 463); + pathB.lineTo(30, 463); + pathB.lineTo(30, 648); + pathB.lineTo(0, 648); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpsergeychunkevich_com8(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(0, 926); + path.lineTo(0, 0); + path.lineTo(1265, 0); + path.lineTo(1265, 926); + path.lineTo(0, 926); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(37, 374); + pathB.lineTo(37, 535); + pathB.cubicTo(37, 536.65686f, 35.6568565f, 538, 34, 538); + pathB.lineTo(1.02866934e-14f, 538); + pathB.lineTo(6.12303177e-17f, 371); + pathB.lineTo(34, 371); + pathB.cubicTo(35.6568565f, 371, 37, 372.34314f, 37, 374); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skptracksflow_com9(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(16, 56); + path.lineTo(32, 56); + path.lineTo(32, 72); + path.lineTo(16, 72); + path.lineTo(16, 56); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kEvenOdd_FillType); + pathB.moveTo(31.65625f, 70.0555649f); + pathB.lineTo(31.65625f, 70.0554962f); + pathB.lineTo(26.9727192f, 65.3615341f); + pathB.cubicTo(27.6210003f, 64.4029694f, 28.0048752f, 63.2470932f, 28.0048752f, 62.0027809f); + pathB.cubicTo(28.0048752f, 58.6875305f, 25.3199062f, 56, 22.0046558f, 56); + pathB.cubicTo(18.6894073f, 56, 16.0031872f, 58.6875305f, 16.0031872f, 62.0027809f); + pathB.cubicTo(16.0031872f, 65.3180008f, 18.6913433f, 68.0055618f, 22.0066261f, 68.0055618f); + pathB.cubicTo(23.2509995f, 68.0055618f, 24.4072189f, 67.6187515f, 25.3657818f, 66.9704056f); + pathB.lineTo(30.0599365f, 71.65625f); + pathB.lineTo(30.0600014f, 71.65625f); + pathB.cubicTo(30.2668133f, 71.875f, 30.5524693f, 71.9992828f, 30.868f, 71.9992828f); + pathB.cubicTo(31.4994049f, 71.9992828f, 32.0014687f, 71.4909363f, 32.0014687f, 70.8595276f); + pathB.cubicTo(32.0015335f, 70.5439072f, 31.875f, 70.2623444f, 31.65625f, 70.0555649f); + pathB.close(); + pathB.moveTo(18.0054054f, 62.0027809f); + pathB.cubicTo(18.0054054f, 59.7925949f, 19.7970943f, 58.0009079f, 22.0072823f, 58.0009079f); + pathB.cubicTo(24.2174377f, 58.0009079f, 26.0091248f, 59.7925949f, 26.0091248f, 62.0027809f); + pathB.cubicTo(26.0091248f, 64.2129364f, 24.2174377f, 66.0046234f, 22.0072803f, 66.0046234f); + pathB.cubicTo(19.7970943f, 66.0045929f, 18.0054054f, 64.2129059f, 18.0054054f, 62.0027809f); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpautobutler_dk29(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(0, 926); + path.lineTo(0, 0); + path.lineTo(1265, 0); + path.lineTo(1265, 926); + path.lineTo(0, 926); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(21, 162); + pathB.lineTo(21, 301); + pathB.lineTo(8.57224448e-15f, 301); + pathB.lineTo(6.12303177e-17f, 162); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skponlinecollege_org144(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(179, 407); + path.cubicTo(177.34314f, 407, 176, 408.34314f, 176, 410); + path.lineTo(176, 436); + path.cubicTo(176, 437.65686f, 177.34314f, 439, 179, 439); + path.lineTo(337.002289f, 439); + path.cubicTo(338.105835f, 438.998779f, 339, 438.103821f, 339, 437); + path.lineTo(339, 409); + path.cubicTo(339, 407.896362f, 338.10611f, 407.001526f, 337.002838f, 407); + path.lineTo(179, 407); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(179, 408); + pathB.lineTo(337, 408); + pathB.cubicTo(338.65686f, 408, 340, 408.895416f, 340, 410); + pathB.lineTo(340, 436); + pathB.cubicTo(340, 437.65686f, 338.65686f, 439, 337, 439); + pathB.lineTo(179, 439); + pathB.cubicTo(177.895432f, 439, 177, 437.65686f, 177, 436); + pathB.lineTo(177, 410); + pathB.cubicTo(177, 408.895416f, 177.895432f, 408, 179, 408); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpnational_com_au81(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(807, 817); + path.quadTo(806.585876f, 817.000122f, 806.292908f, 817.292908f); + path.quadTo(806.000122f, 817.585876f, 806, 818); + path.lineTo(806, 881); + path.lineTo(1111, 881); + path.lineTo(1111, 818); + path.quadTo(1110.99988f, 817.585876f, 1110.70715f, 817.292908f); + path.quadTo(1110.41406f, 817.000122f, 1110, 817); + path.lineTo(807, 817); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(807, 817); + pathB.lineTo(1110, 817); + pathB.cubicTo(1110.55225f, 817, 1111, 817.447693f, 1111, 818); + pathB.lineTo(1111, 880); + pathB.lineTo(806, 880); + pathB.lineTo(806, 818); + pathB.cubicTo(806, 817.447693f, 806.447693f, 817, 807, 817); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skprentacheat_com30(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(967, 263); + path.quadTo(966.585876f, 263.000092f, 966.292908f, 263.292908f); + path.quadTo(966.000122f, 263.585876f, 966, 264); + path.lineTo(966, 301); + path.lineTo(1214, 301); + path.lineTo(1214, 264); + path.quadTo(1213.99988f, 263.585876f, 1213.70715f, 263.292908f); + path.quadTo(1213.41406f, 263.000092f, 1213, 263); + path.lineTo(967, 263); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(967, 263); + pathB.lineTo(1213, 263); + pathB.cubicTo(1213.55225f, 263, 1214, 263.447723f, 1214, 264); + pathB.lineTo(1214, 300); + pathB.lineTo(966, 300); + pathB.lineTo(966, 264); + pathB.cubicTo(966, 263.447723f, 966.447693f, 263, 967, 263); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpbreakmystyle_com10(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(271.032867f, -5.32907052e-15f); + path.lineTo(56.9671326f, -5.16253706e-15f); + path.quadTo(52.7835083f, 3.69968891f, 48.7416f, 7.74160004f); + path.quadTo(1, 55.4831848f, 1, 123); + path.quadTo(1, 190.516815f, 48.7416f, 238.258392f); + path.quadTo(96.4831848f, 286, 164, 286); + path.quadTo(231.516815f, 286, 279.258392f, 238.258392f); + path.quadTo(327, 190.516815f, 327, 123); + path.quadTo(327, 55.4831848f, 279.258392f, 7.74160004f); + path.quadTo(275.216431f, 3.69964004f, 271.032867f, -5.32907052e-15f); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(327, 123); + pathB.quadTo(327, 190.516815f, 279.258392f, 238.258392f); + pathB.quadTo(231.516815f, 286, 164, 286); + pathB.quadTo(96.4831848f, 286, 48.7416f, 238.258392f); + pathB.quadTo(1, 190.516815f, 1, 123); + pathB.quadTo(1, 55.4831848f, 48.7416f, 7.74160004f); + pathB.quadTo(96.4831848f, -40, 164, -40); + pathB.quadTo(231.516815f, -40, 279.258392f, 7.74160004f); + pathB.quadTo(327, 55.4831848f, 327, 123); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpsd_graphic_net104(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(475.421448f, 836.985962f); + path.lineTo(461.280975f, 841.990662f); + path.cubicTo(466.80899f, 857.609802f, 458.62854f, 874.752991f, 443.009399f, 880.281006f); + path.cubicTo(435.199829f, 883.044983f, 427.009247f, 882.381897f, 420.080048f, 879.075378f); + path.lineTo(413.620056f, 892.613037f); + path.quadTo(430.419983f, 900.629761f, 447.96701f, 894.43811f); + path.quadTo(448.00708f, 894.42395f, 448.014038f, 894.421509f); + path.quadTo(448.043976f, 894.410889f, 448.061066f, 894.404846f); + path.quadTo(465.596313f, 888.179932f, 473.613037f, 871.379944f); + path.quadTo(477.351227f, 863.546143f, 478, 855.549866f); + path.lineTo(478, 848.804321f); + path.quadTo(477.528076f, 842.93811f, 475.421448f, 836.985962f); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(405.592621f, 909.435547f); + pathB.lineTo(390.578583f, 867.014099f); + pathB.lineTo(433, 852.000061f); + pathB.lineTo(490.435486f, 879.40741f); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +#if TRY_BROKEN_TESTS +/* this cubic/quad pair + c = 430,280 430,278.895416 473.876068,278 528,278 + q = 430,280 430.009796,277.101196 458.703552,275.050262 + only intersect at the shared point (430,280) + they sort backwards because the tangent from pt[0] to control pt[1] + c' = (0.00000000000000000, -1.1045837402343750) + q' = (0.0097961425781250000, -2.8988037109375000)
+ suggests that the quad is counterclockwise of the cubic, when the reverse is true
+ the angle code is fooled because the control pt[1] of both the quad and cubic
+ is far away from cubic cntl [2] and quad pt [2].
+ Maybe in angle setup, this instability can be detected to suppress sorting on the initial tangent
+ Or the error term can be passed to NearRay that is magnified by the distance from the next ctrl?
+ */ +static void skpnaoxrane_ru23(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(458.703552f, 275.050262f); + path.quadTo(487.41687f, 273.000702f, 528, 273); + path.lineTo(529, 273); + path.quadTo(530.242371f, 273.000305f, 531.121338f, 273.878693f); + path.quadTo(531.999695f, 274.75766f, 532, 276); + path.lineTo(532, 378); + path.quadTo(531.990173f, 380.898804f, 503.296448f, 382.949738f); + path.quadTo(474.58313f, 384.999298f, 434, 385); + path.lineTo(433, 385); + path.quadTo(431.75766f, 384.999695f, 430.878693f, 384.121307f); + path.quadTo(430.000305f, 383.24234f, 430, 382); + path.lineTo(430, 280); + path.quadTo(430.009796f, 277.101196f, 458.703552f, 275.050262f); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(528, 278); + pathB.lineTo(529, 278); + pathB.cubicTo(530.65686f, 278, 532, 278, 532, 278); + pathB.lineTo(532, 378); + pathB.cubicTo(532, 379.104584f, 488.123932f, 380, 434, 380); + pathB.lineTo(433, 380); + pathB.cubicTo(431.34314f, 380, 430, 380, 430, 380); + pathB.lineTo(430, 280); + pathB.cubicTo(430, 278.895416f, 473.876068f, 278, 528, 278); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +/* didn't investigate thoroughly, but looks to be missorting quad and cubic + {{468.507751,560.724426}, {467.275146,552.856262}, {465.84668,547.288391}} + {{463.779907,542.671143}, {464.829529,542.672974}, {466.946289,550.755676}, {468.507751,560.724426}} + decision maker is case 14 leftLessThanRight + */ +static void skptcmevents_org23(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(465.503998f, 546); + path.lineTo(347, 546); + path.lineTo(347, 632); + path.lineTo(469.104248f, 632); + path.quadTo(470.79007f, 627.638672f, 471.833496f, 621.036255f); + path.quadTo(474.902588f, 601.562866f, 470.591064f, 574.024353f); + path.lineTo(468.507751f, 560.724426f); + path.quadTo(467.275146f, 552.856262f, 465.84668f, 547.288391f); + path.quadTo(465.670349f, 546.601501f, 465.503998f, 546); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(363.052246f, 542.495361f); + pathB.lineTo(463.779907f, 542.671143f); + pathB.cubicTo(464.829529f, 542.672974f, 466.946289f, 550.755676f, 468.507751f, 560.724426f); + pathB.lineTo(470.591064f, 574.024353f); + pathB.cubicTo(476.26178f, 610.226624f, 471.498932f, 639.557922f, 459.953003f, 639.537781f); + pathB.lineTo(368.727936f, 639.378601f); + pathB.cubicTo(351.933868f, 639.349304f, 337.053741f, 631.244324f, 335.492249f, 621.275574f); + pathB.lineTo(325.968597f, 560.475708f); + pathB.cubicTo(324.407104f, 550.506958f, 341.01001f, 542.456909f, 363.052246f, 542.495361f); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpredbullskatearcade_es16(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(936.765625f, 458.965302f); + path.cubicTo(937.028442f, 453.863251f, 933.145813f, 449.864502f, 928.093445f, 450.033905f); + path.lineTo(661.882263f, 458.958862f); + path.lineTo(661.875366f, 458.959106f); + path.cubicTo(656.828369f, 459.13205f, 652.525085f, 463.399719f, 652.258545f, 468.496124f); + path.lineTo(652.258179f, 468.503662f); + path.lineTo(649.021729f, 531.322754f); + path.cubicTo(648.75885f, 536.424805f, 652.641479f, 540.423523f, 657.693848f, 540.25415f); + path.lineTo(923.905029f, 531.329163f); + path.cubicTo(928.955017f, 531.159851f, 933.262268f, 526.890442f, 933.528809f, 521.791565f); + path.lineTo(933.529175f, 521.784363f); + path.lineTo(936.765625f, 458.965302f); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(661.882263f, 458.958862f); + pathB.lineTo(928.093445f, 450.033905f); + pathB.cubicTo(929.103882f, 450, 929.709961f, 454.108612f, 929.447144f, 459.210663f); + pathB.lineTo(926.210693f, 522.029724f); + pathB.cubicTo(926.079224f, 524.58075f, 925.153442f, 526.676208f, 924.143066f, 526.710083f); + pathB.lineTo(657.931885f, 535.635071f); + pathB.cubicTo(652.879456f, 535.804443f, 648.890259f, 533.873779f, 649.021729f, 531.322754f); + pathB.lineTo(652.258179f, 468.503662f); + pathB.cubicTo(652.520996f, 463.401611f, 656.829834f, 459.128235f, 661.882263f, 458.958862f); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpfinanzasdigital_com9(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(156, 126); + path.quadTo(154.343552f, 126.000397f, 153.17157f, 127.17157f); + path.quadTo(152.000397f, 128.343552f, 152, 130); + path.lineTo(152, 174); + path.lineTo(1114, 174); + path.lineTo(1114, 130); + path.quadTo(1113.99963f, 128.343552f, 1112.82837f, 127.17157f); + path.quadTo(1111.65649f, 126.000397f, 1110, 126); + path.lineTo(156, 126); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(156, 126); + pathB.lineTo(1110, 126); + pathB.cubicTo(1111.65686f, 126, 1113, 127.790863f, 1113, 130); + pathB.lineTo(1113, 174); + pathB.lineTo(153, 174); + pathB.lineTo(153, 130); + pathB.cubicTo(153, 127.790863f, 154.34314f, 126, 156, 126); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} +#endif + +static void skppartainasdemo250_org56(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(182.000015f, 645); + path.lineTo(182, 640); + path.cubicTo(174.322327f, 640, 166.644669f, 637.071045f, 160.786804f, 631.213196f); + path.cubicTo(149.071075f, 619.497437f, 149.071075f, 600.502563f, 160.786804f, 588.786804f); + path.lineTo(157.251266f, 585.251221f); + path.quadTo(147, 595.502502f, 147.000015f, 610); + path.quadTo(147, 624.482605f, 157.230255f, 634.727722f); + path.quadTo(157.251251f, 634.748779f, 157.251282f, 634.748779f); + path.quadTo(157.282852f, 634.780334f, 157.272263f, 634.769775f); + path.quadTo(167.517334f, 645, 182.000015f, 645); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(182, 659.497498f); + pathB.lineTo(206.748749f, 634.748718f); + pathB.lineTo(182.000015f, 610); + pathB.lineTo(132.502533f, 610); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpmlk_com326(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(154, 670); + path.cubicTo(151.238571f, 670, 149, 672.238586f, 149, 675); + path.lineTo(149, 710.001465f); + path.cubicTo(149.000809f, 712.209961f, 150.791367f, 714, 153, 714); + path.lineTo(189, 714); + path.cubicTo(191.209137f, 714, 193, 712.209167f, 193, 710); + path.lineTo(193, 675); + path.cubicTo(193, 672.238586f, 190.761429f, 670, 188, 670); + path.lineTo(154, 670); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(154, 671); + pathB.lineTo(188, 671); + pathB.cubicTo(190.761429f, 671, 193, 672.790833f, 193, 675); + pathB.lineTo(193, 710); + pathB.cubicTo(193, 712.761414f, 190.761429f, 715, 188, 715); + pathB.lineTo(154, 715); + pathB.cubicTo(151.238571f, 715, 149, 712.761414f, 149, 710); + pathB.lineTo(149, 675); + pathB.cubicTo(149, 672.790833f, 151.238571f, 671, 154, 671); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpcyclist_friends_gr52(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(50, 182); + path.lineTo(1215, 182); + path.lineTo(1215, 202); + path.quadTo(1214.99951f, 204.070572f, 1213.53552f, 205.535538f); + path.quadTo(1212.07056f, 206.999496f, 1210, 207); + path.lineTo(55, 207); + path.quadTo(52.9294319f, 206.999496f, 51.4644661f, 205.535538f); + path.quadTo(50.0004997f, 204.070572f, 50, 202); + path.lineTo(50, 182); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(50, 183); + pathB.lineTo(1215, 183); + pathB.lineTo(1215, 202); + pathB.cubicTo(1215, 204.761429f, 1212.76147f, 207, 1210, 207); + pathB.lineTo(55, 207); + pathB.cubicTo(52.238575f, 207, 50, 204.761429f, 50, 202); + pathB.lineTo(50, 183); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +/* cubic ends just above opp line */ +static void skpwww_fj_p_com_22(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(172, 201); + path.lineTo(172, 202); + path.lineTo(220, 202); + path.cubicTo(221.65686f, 202, 223, 200.65686f, 223, 199); + path.cubicTo(223, 200.104568f, 221.65686f, 201, 220, 201); + path.lineTo(172, 201); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(161, 202); + pathB.lineTo(161, 199); + pathB.lineTo(223, 199.000015f); + pathB.lineTo(223, 202); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +#define TRY_SEPT_BROKEN_TESTS 0 +#if TRY_SEPT_BROKEN_TESTS +// pair of lines are not quite coincident, so sorting line/cubic fails (i think) +static void skpwww_lavoixdunord_fr_11(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(806, 57); + path.cubicTo(806, 55.3431473f, 807.34314f, 54, 809, 54); + path.lineTo(930, 54); + path.cubicTo(931.65686f, 54, 933, 55.3431473f, 933, 57); + path.lineTo(933, 91); + path.cubicTo(933, 92.6568527f, 931.65686f, 94, 930, 94); + path.lineTo(809, 94); + path.cubicTo(807.34314f, 94, 806, 92.6568527f, 806, 91); + path.lineTo(806, 57); + path.close(); + path.moveTo(808, 58); + path.cubicTo(808, 56.8954315f, 808.895447f, 56, 810, 56); + path.lineTo(929, 56); + path.cubicTo(930.104553f, 56, 931, 56.8954315f, 931, 58); + path.lineTo(931, 90); + path.cubicTo(931, 91.1045685f, 930.104553f, 92, 929, 92); + path.lineTo(810, 92); + path.cubicTo(808.895447f, 92, 808, 91.1045685f, 808, 90); + path.lineTo(808, 58); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(806, 54); + pathB.lineTo(808, 56); + pathB.lineTo(935.02002f, 56.0200005f); + pathB.lineTo(933, 54); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +// pair of curves have nearly the same initial tangent but are sorting by +// that alone sorts them incorrectly. Need to detect that tangents are nearly +// identical and not reliable by themselves +static void skppptv_com_62(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(173, 5342); + path.quadTo(171.343536f, 5342.00049f, 170.17157f, 5343.17139f); + path.quadTo(169.000397f, 5344.34375f, 169, 5346); + path.lineTo(169, 5372); + path.lineTo(234, 5372); + path.lineTo(234, 5346); + path.quadTo(233.999603f, 5344.34375f, 232.82843f, 5343.17139f); + path.quadTo(231.656464f, 5342.00049f, 230, 5342); + path.lineTo(173, 5342); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(173, 5342); + pathB.lineTo(230, 5342); + pathB.cubicTo(231.65686f, 5342, 233, 5343.79102f, 233, 5346); + pathB.lineTo(233, 5372); + pathB.lineTo(169, 5372); + pathB.lineTo(169, 5346); + pathB.cubicTo(169, 5343.79102f, 170.790863f, 5342, 173, 5342); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +// nearly identical to lavoixdunord -- to not-quite-coincident lines +static void skpwww_booking_com_68(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(90, 187); + path.cubicTo(90, 185.34314f, 91.3431473f, 184, 93, 184); + path.lineTo(588, 184); + path.cubicTo(589.65686f, 184, 591, 185.34314f, 591, 187); + path.lineTo(591, 218); + path.cubicTo(591, 219.65686f, 589.65686f, 221, 588, 221); + path.lineTo(93, 221); + path.cubicTo(91.3431473f, 221, 90, 219.65686f, 90, 218); + path.lineTo(90, 187); + path.close(); + path.moveTo(92, 188); + path.cubicTo(92, 186.895432f, 92.8954315f, 186, 94, 186); + path.lineTo(587, 186); + path.cubicTo(588.104553f, 186, 589, 186.895432f, 589, 188); + path.lineTo(589, 217); + path.cubicTo(589, 218.104568f, 588.104553f, 219, 587, 219); + path.lineTo(94, 219); + path.cubicTo(92.8954315f, 219, 92, 218.104568f, 92, 217); + path.lineTo(92, 188); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(90, 184); + pathB.lineTo(92, 186); + pathB.lineTo(593.02002f, 186.020004f); + pathB.lineTo(591, 184); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +// visually looks like lavoixdunord and www_booking_com +static void skpwww_despegar_com_mx_272(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(635, 1788); + path.cubicTo(635, 1786.34314f, 636.34314f, 1785, 638, 1785); + path.lineTo(832, 1785); + path.cubicTo(833.65686f, 1785, 835, 1786.34314f, 835, 1788); + path.lineTo(835, 1812); + path.cubicTo(835, 1813.65686f, 833.65686f, 1815, 832, 1815); + path.lineTo(638, 1815); + path.cubicTo(636.34314f, 1815, 635, 1813.65686f, 635, 1812); + path.lineTo(635, 1788); + path.close(); + path.moveTo(637, 1789); + path.cubicTo(637, 1787.89539f, 637.895447f, 1787, 639, 1787); + path.lineTo(831, 1787); + path.cubicTo(832.104553f, 1787, 833, 1787.89539f, 833, 1789); + path.lineTo(833, 1811); + path.cubicTo(833, 1812.10461f, 832.104553f, 1813, 831, 1813); + path.lineTo(639, 1813); + path.cubicTo(637.895447f, 1813, 637, 1812.10461f, 637, 1811); + path.lineTo(637, 1789); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(835, 1785); + pathB.lineTo(833, 1787); + pathB.lineTo(832.97998f, 1817.02002f); + pathB.lineTo(835, 1815); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} +#endif + +static void skpwww_joomla_org_23(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(320, 347); + path.cubicTo(320, 344.238586f, 322.238586f, 342, 325, 342); + path.lineTo(416, 342); + path.cubicTo(418.761414f, 342, 421, 344.238586f, 421, 347); + path.cubicTo(421, 344.790863f, 418.761414f, 343, 416, 343); + path.lineTo(325, 343); + path.cubicTo(322.238586f, 343, 320, 344.790863f, 320, 347); + path.close(); + path.moveTo(320, 378); + path.cubicTo(320, 380.761414f, 322.238586f, 383, 325, 383); + path.lineTo(416, 383); + path.cubicTo(418.761414f, 383, 421, 380.761414f, 421, 378); + path.cubicTo(421, 380.209137f, 418.761414f, 382, 416, 382); + path.lineTo(325, 382); + path.cubicTo(322.238586f, 382, 320, 380.209137f, 320, 378); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(320, 383); + pathB.lineTo(320, 378); + pathB.lineTo(421, 378.000031f); + pathB.lineTo(421, 383); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpwww_macrumors_com_131(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(136, 14089); + path.lineTo(136, 14056); + path.lineTo(778, 14056); + path.lineTo(778, 14089); + path.quadTo(777.999573f, 14090.6562f, 776.82843f, 14091.8281f); + path.quadTo(775.656433f, 14093, 774, 14093); + path.lineTo(140, 14093); + path.quadTo(138.343552f, 14093, 137.17157f, 14091.8281f); + path.quadTo(136.000397f, 14090.6562f, 136, 14089); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kInverseWinding_FillType); + pathB.moveTo(136, 14057); + pathB.lineTo(778, 14057); + pathB.lineTo(778, 14089); + pathB.cubicTo(778, 14091.209f, 776.209167f, 14093, 774, 14093); + pathB.lineTo(140, 14093); + pathB.cubicTo(137.790863f, 14093, 136, 14091.209f, 136, 14089); + pathB.lineTo(136, 14057); + pathB.close(); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpwww_leadpages_net_84(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(377.1716f, 5910.17139f); + path.cubicTo(376.447723f, 5910.89551f, 376, 5911.89551f, 376, 5913); + path.lineTo(376, 5972); + path.cubicTo(376, 5974.20898f, 377.790863f, 5976, 380, 5976); + path.cubicTo(378.34314f, 5976, 377, 5974.20898f, 377, 5972); + path.lineTo(377, 5913); + path.cubicTo(377, 5912.17139f, 377.335785f, 5911.42188f, 377.878693f, 5910.87891f); + path.lineTo(377.1716f, 5910.17139f); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(376, 5909); + pathB.lineTo(378.481873f, 5909); + pathB.lineTo(379.999878f, 5976); + pathB.lineTo(376, 5976); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +static void skpwww_briian_com_34(skiatest::Reporter* reporter) { + SkPath path; + path.setFillType(SkPath::kEvenOdd_FillType); + path.moveTo(843, 216); + path.cubicTo(843, 213.238571f, 845.238586f, 211, 848, 211); + path.lineTo(1191, 211); + path.cubicTo(1193.76147f, 211, 1196, 213.238571f, 1196, 216); + path.lineTo(1196, 779); + path.cubicTo(1196, 781.761414f, 1193.76147f, 784, 1191, 784); + path.lineTo(848, 784); + path.cubicTo(845.238586f, 784, 843, 781.761414f, 843, 779); + path.lineTo(843, 216); + path.close(); + path.moveTo(844, 217); + path.cubicTo(844, 214.238571f, 846.238586f, 212, 849, 212); + path.lineTo(1190, 212); + path.cubicTo(1192.76147f, 212, 1195, 214.238571f, 1195, 217); + path.lineTo(1195, 778); + path.cubicTo(1195, 779.65686f, 1192.76147f, 781, 1190, 781); + path.lineTo(849, 781); + path.cubicTo(846.238586f, 781, 844, 779.65686f, 844, 778); + path.lineTo(844, 217); + path.close(); + SkPath pathB; + pathB.setFillType(SkPath::kWinding_FillType); + pathB.moveTo(843, 784); + pathB.lineTo(843, 779); + pathB.lineTo(1196, 779.000061f); + pathB.lineTo(1196, 784); + testPathOp(reporter, path, pathB, kIntersect_PathOp); +} + +
+static void skpwww_sciality_com_100(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(162, 468);
+ path.cubicTo(159.790863f, 468, 158, 469.790863f, 158, 472);
+ path.lineTo(158, 528);
+ path.cubicTo(158, 530.209106f, 159.790863f, 532, 162, 532);
+ path.lineTo(275, 532);
+ path.cubicTo(277.209137f, 532, 279, 530.209106f, 279, 528);
+ path.lineTo(279, 472);
+ path.cubicTo(279, 469.790863f, 277.209137f, 468, 275, 468);
+ path.lineTo(162, 468);
+ path.close();
+ SkPath pathB;
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(275, 468);
+ pathB.cubicTo(276.65686f, 468, 278, 469.34314f, 278, 471);
+ pathB.lineTo(278, 529);
+ pathB.cubicTo(278, 530.65686f, 276.65686f, 532, 275, 532);
+ pathB.lineTo(161, 532);
+ pathB.cubicTo(159.34314f, 532, 158, 530.65686f, 158, 529);
+ pathB.lineTo(158, 471);
+ pathB.cubicTo(158, 469.34314f, 159.34314f, 468, 161, 468);
+ pathB.lineTo(275, 468);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+
+#if TRY_SEPT_BROKEN_TESTS +static void skpwww_sciality_com_101(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(162, 468);
+ path.cubicTo(159.790863f, 468, 158, 469.790863f, 158, 472);
+ path.lineTo(158, 528);
+ path.cubicTo(158, 530.209106f, 159.790863f, 532, 162, 532);
+ path.lineTo(275.009186f, 532);
+ path.cubicTo(276.661774f, 531.994995f, 278, 530.653748f, 278, 529);
+ path.lineTo(278, 471);
+ path.cubicTo(278, 469.346375f, 276.662079f, 468.005249f, 275.009705f, 468);
+ path.lineTo(162, 468);
+ path.close();
+ SkPath pathB;
+ pathB.setFillType(SkPath::kInverseWinding_FillType);
+ pathB.moveTo(161, 469);
+ pathB.lineTo(275, 469);
+ pathB.cubicTo(276.65686f, 469, 278, 469.895416f, 278, 471);
+ pathB.lineTo(278, 529);
+ pathB.cubicTo(278, 530.65686f, 276.65686f, 532, 275, 532);
+ pathB.lineTo(161, 532);
+ pathB.cubicTo(159.34314f, 532, 158, 530.65686f, 158, 529);
+ pathB.lineTo(158, 471);
+ pathB.cubicTo(158, 469.895416f, 159.34314f, 469, 161, 469);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
#endif +static void skpwww_meb_gov_tr_5(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(137.34314f, 145.34314f);
+ path.quadTo(139.687088f, 143.000793f, 143, 143);
+ path.lineTo(242, 143);
+ path.quadTo(245.312912f, 143.000793f, 247.65686f, 145.34314f);
+ path.quadTo(249.999207f, 147.687088f, 250, 151);
+ path.lineTo(250, 177);
+ path.lineTo(135, 177);
+ path.lineTo(135, 151);
+ path.quadTo(135.000793f, 147.687088f, 137.34314f, 145.34314f);
+ path.close();
+ SkPath pathB;
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(135, 143);
+ pathB.lineTo(250, 143);
+ pathB.lineTo(250, 177);
+ pathB.lineTo(135, 177);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+
+#if TRY_SEPT_BROKEN_TESTS +static void skpwww_meb_gov_tr_6(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(143, 143);
+ path.quadTo(139.687088f, 143.000793f, 137.34314f, 145.34314f);
+ path.quadTo(135.000793f, 147.687088f, 135, 151);
+ path.lineTo(135, 177);
+ path.lineTo(250, 177);
+ path.lineTo(250, 151);
+ path.quadTo(249.999207f, 147.687088f, 247.65686f, 145.34314f);
+ path.quadTo(245.312912f, 143.000793f, 242, 143);
+ path.lineTo(143, 143);
+ path.close();
+ SkPath pathB;
+ pathB.setFillType(SkPath::kInverseWinding_FillType);
+ pathB.moveTo(143, 143);
+ pathB.lineTo(242, 143);
+ pathB.cubicTo(245.865997f, 143, 249, 146.581726f, 249, 151);
+ pathB.lineTo(249, 177);
+ pathB.lineTo(135, 177);
+ pathB.lineTo(135, 151);
+ pathB.cubicTo(135, 146.581726f, 138.581726f, 143, 143, 143);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+#endif + +static void skpgithub_io_25(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(1001.87866f, 14.8786793f);
+ path.quadTo(1002.75745f, 14.0001001f, 1004, 14);
+ path.lineTo(1105, 14);
+ path.quadTo(1106.24255f, 14.0001001f, 1107.12134f, 14.8786793f);
+ path.quadTo(1107.99988f, 15.7574596f, 1108, 17);
+ path.lineTo(1108, 41);
+ path.quadTo(1107.99988f, 42.2425423f, 1107.12134f, 43.1213188f);
+ path.quadTo(1106.24255f, 43.9999008f, 1105, 44);
+ path.lineTo(1004, 44);
+ path.quadTo(1002.75745f, 43.9999008f, 1001.87866f, 43.1213188f);
+ path.quadTo(1001.00012f, 42.2425423f, 1001, 41);
+ path.lineTo(1001, 17);
+ path.quadTo(1001.00012f, 15.7574596f, 1001.87866f, 14.8786793f);
+ path.close();
+ SkPath pathB;
+ pathB.setFillType(SkPath::kInverseWinding_FillType);
+ pathB.moveTo(1005, 16);
+ pathB.lineTo(1104, 16);
+ pathB.cubicTo(1105.10461f, 16, 1106, 16.8954296f, 1106, 18);
+ pathB.lineTo(1106, 40);
+ pathB.cubicTo(1106, 41.1045685f, 1105.10461f, 42, 1104, 42);
+ pathB.lineTo(1005, 42);
+ pathB.cubicTo(1003.89545f, 42, 1003, 41.1045685f, 1003, 40);
+ pathB.lineTo(1003, 18);
+ pathB.cubicTo(1003, 16.8954296f, 1003.89545f, 16, 1005, 16);
+ pathB.close();
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+
+static void skpgithub_io_26(skiatest::Reporter* reporter) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.moveTo(1001.87866f, 14.8786793f);
+ path.quadTo(1002.75745f, 14.0001001f, 1004, 14);
+ path.lineTo(1105, 14);
+ path.quadTo(1106.24255f, 14.0001001f, 1107.12134f, 14.8786793f);
+ path.quadTo(1107.99988f, 15.7574596f, 1108, 17);
+ path.lineTo(1108, 41);
+ path.quadTo(1107.99988f, 42.2425423f, 1107.12134f, 43.1213188f);
+ path.quadTo(1106.24255f, 43.9999008f, 1105, 44);
+ path.lineTo(1004, 44);
+ path.quadTo(1002.75745f, 43.9999008f, 1001.87866f, 43.1213188f);
+ path.quadTo(1001.00012f, 42.2425423f, 1001, 41);
+ path.lineTo(1001, 17);
+ path.quadTo(1001.00012f, 15.7574596f, 1001.87866f, 14.8786793f);
+ path.close();
+ path.moveTo(1003, 18);
+ path.cubicTo(1003, 16.8954296f, 1003.89545f, 16, 1005, 16);
+ path.lineTo(1104, 16);
+ path.cubicTo(1105.10461f, 16, 1106, 16.8954296f, 1106, 18);
+ path.lineTo(1106, 40);
+ path.cubicTo(1106, 41.1045685f, 1105.10461f, 42, 1104, 42);
+ path.lineTo(1005, 42);
+ path.cubicTo(1003.89545f, 42, 1003, 41.1045685f, 1003, 40);
+ path.lineTo(1003, 18);
+ path.close();
+ SkPath pathB;
+ pathB.setFillType(SkPath::kWinding_FillType);
+ pathB.moveTo(1108, 14);
+ pathB.lineTo(1106, 16);
+ pathB.lineTo(1105.97998f, 46.0200005f);
+ pathB.lineTo(1108, 44);
+ testPathOp(reporter, path, pathB, kIntersect_PathOp);
+}
+ static void (*firstTest)(skiatest::Reporter* ) = 0; static struct TestDesc tests[] = { +#if TRY_SEPT_BROKEN_TESTS + TEST(skpwww_meb_gov_tr_6), + TEST(skpwww_sciality_com_101), + TEST(skpwww_booking_com_68), // similar to lavoixdunord + TEST(skpwww_despegar_com_mx_272), // similar to lavoixdunord + TEST(skpwww_lavoixdunord_fr_11), // not quite coincident, sorting line/cubic fails + TEST(skppptv_com_62), // cubic have nearly identical tangents, sort incorrectly +#endif #if TRY_BROKEN_TESTS TEST(skppchappy_com_au102), TEST(skpsciality_com161), - TEST(skpsudoestenegocios_com186), - TEST(skpfrauen_magazin_com83), TEST(skpi_gino_com16), + TEST(skpnaoxrane_ru23), // see test for failure evaluation + TEST(skptcmevents_org23), // see test for (partial) failure evaluation + TEST(skpredbullskatearcade_es16), // cubic have nearly identical tangents, sort incorrectly + TEST(skpfinanzasdigital_com9), // cubic/quad tangents too close to sort #endif + TEST(skpgithub_io_26), + TEST(skpgithub_io_25), + TEST(skpwww_meb_gov_tr_5), + TEST(skpwww_sciality_com_100), + TEST(skpwww_joomla_org_23), + TEST(skpwww_macrumors_com_131), + TEST(skpwww_briian_com_34), + TEST(skpwww_leadpages_net_84), + TEST(skpwww_fj_p_com_22), + TEST(skppartainasdemo250_org56), + TEST(skpsd_graphic_net104), + TEST(skpbreakmystyle_com10), + TEST(skpnational_com_au81), + TEST(skprentacheat_com30), + TEST(skptracksflow_com9), + TEST(skpautobutler_dk29), + TEST(skponlinecollege_org144), + TEST(skphostloco_com11), + TEST(skpsergeychunkevich_com8), + TEST(skpmlk_com326), + TEST(skpcyclist_friends_gr52), + TEST(skpfrauen_magazin_com83), + TEST(skpthesuburbanite_com213), + TEST(skpsudoestenegocios_com186), TEST(skpmtrk_uz27), TEST(skpilkoora_com37), TEST(skpmm4everfriends_com43), diff --git a/tests/PathOpsThreadedCommon.h b/tests/PathOpsThreadedCommon.h index ee9339065f..a638cd2fdf 100644 --- a/tests/PathOpsThreadedCommon.h +++ b/tests/PathOpsThreadedCommon.h @@ -68,6 +68,15 @@ public: fTestFun = testFun; } + PathOpsThreadedRunnable(void (*testFun)(PathOpsThreadState*), int dirNo, const char* str, + PathOpsThreadedTestRunner* runner) { + SkASSERT(strlen(str) < sizeof(fState.fSerialNo) - 1); + fState.fA = dirNo; + strcpy(fState.fSerialNo, str); + fState.fReporter = runner->fReporter; + fTestFun = testFun; + } + virtual void run() SK_OVERRIDE { SkBitmap bitmap; fState.fBitmap = &bitmap; diff --git a/tests/PathOpsTypesTest.cpp b/tests/PathOpsTypesTest.cpp new file mode 100755 index 0000000000..6fd6e10e7d --- /dev/null +++ b/tests/PathOpsTypesTest.cpp @@ -0,0 +1,24 @@ +/* + * Copyright 2013 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "PathOpsTestCommon.h" +#include "Test.h" +
+static const double roughlyTests[][2] = {
+ {5.0402503619650929e-005, 4.3178054475078825e-005}
+};
+
+static const size_t roughlyTestsCount = SK_ARRAY_COUNT(roughlyTests); +
+static void PathOpsRoughlyTest(skiatest::Reporter* reporter) { + for (size_t index = 0; index < roughlyTestsCount; ++index) { + bool equal = RoughlyEqualUlps(roughlyTests[index][0], roughlyTests[index][1]); + REPORTER_ASSERT(reporter, equal); + } +}
+
+#include "TestClassDef.h" +DEFINE_TESTCLASS_SHORT(PathOpsRoughlyTest) diff --git a/tests/SkpSkGrTest.cpp b/tests/SkpSkGrTest.cpp new file mode 100755 index 0000000000..d26659f5c3 --- /dev/null +++ b/tests/SkpSkGrTest.cpp @@ -0,0 +1,759 @@ +#if !SK_SUPPORT_GPU +#error "GPU support required" +#endif + +#include "GrContext.h" +#include "GrContextFactory.h" +#include "GrRenderTarget.h" +#include "SkGpuDevice.h" +#include "gl/GrGLDefines.h" + +#include "SkBitmap.h" +#include "SkColor.h" +#include "SkDevice.h" +#include "SkCanvas.h" +#include "SkGraphics.h" +#include "SkImageDecoder.h" +#include "SkImageEncoder.h" +#include "SkStream.h" +#include "SkOSFile.h" +#include "SkPicture.h" +#include "SkRTConf.h" +#include "SkRunnable.h" +#include "SkString.h" +#include "SkTArray.h" +#include "SkTDArray.h" +#include "SkThreadPool.h" +#include "SkTime.h" +#include "Test.h" + +#ifdef SK_BUILD_FOR_WIN + #define PATH_SLASH "\\" + #define IN_DIR "D:\\9-30-13\\" + #define OUT_DIR "D:\\skpSkGr\\11\\" + #define LINE_FEED "\r\n" +#else + #define PATH_SLASH "/" + #define IN_DIR "/usr/local/google/home/caryclark" PATH_SLASH "9-30-13-skp" + #define OUT_DIR "/media/01CD75512A7F9EE0/4" PATH_SLASH + #define LINE_FEED \n" +#endif + +#define PATH_STR_SIZE 512 + +static const struct { + int directory; + const char* filename; +} skipOverSkGr[] = { + {1, "http___accuweather_com_.skp"}, // Couldn't convert bitmap to texture.http___absoku072_com_ +}; + +static const size_t skipOverSkGrCount = 0; // SK_ARRAY_COUNT(skipOverSkGr); + +///////////////////////////////////////// + +class SkpSkGrThreadedRunnable; + +enum TestStep { + kCompareBits, + kEncodeFiles, +}; + +enum { + kMaxLength = 128, + kMaxFiles = 128, +}; + +struct TestResult { + void init(int dirNo) { + fDirNo = dirNo; + sk_bzero(fFilename, sizeof(fFilename)); + fTestStep = kCompareBits; + fScaleOversized = true; + } + + SkString status() { + SkString outStr; + outStr.printf("%s %d %d%s", fFilename, fPixelError, fTime, LINE_FEED); + return outStr; + } + + static void Test(int dirNo, const char* filename, TestStep testStep, bool verbose) { + TestResult test; + test.init(dirNo); + test.fTestStep = testStep; + strcpy(test.fFilename, filename); + test.testOne(); + if (verbose) { + SkDebugf("%s", test.status().c_str()); + } + } + + void test(int dirNo, const SkString& filename) { + init(dirNo); + strcpy(fFilename, filename.c_str()); + testOne(); + } + + void testOne(); + + char fFilename[kMaxLength]; + TestStep fTestStep; + int fDirNo; + int fPixelError; + int fTime; + bool fScaleOversized; +}; + +struct SkpSkGrThreadState { + void init(int dirNo) { + fResult.init(dirNo); + fFoundCount = 0; + fSmallestError = 0; + sk_bzero(fFilesFound, sizeof(fFilesFound)); + sk_bzero(fDirsFound, sizeof(fDirsFound)); + sk_bzero(fError, sizeof(fError)); + } + + char fFilesFound[kMaxFiles][kMaxLength]; + int fDirsFound[kMaxFiles]; + int fError[kMaxFiles]; + int fFoundCount; + int fSmallestError; + skiatest::Reporter* fReporter; + TestResult fResult; +}; + +struct SkpSkGrThreadedTestRunner { + SkpSkGrThreadedTestRunner(skiatest::Reporter* reporter, int threadCount) + : fNumThreads(threadCount) + , fReporter(reporter) { + } + + ~SkpSkGrThreadedTestRunner(); + void render(); + int fNumThreads; + SkTDArray<SkpSkGrThreadedRunnable*> fRunnables; + skiatest::Reporter* fReporter; +}; + +class SkpSkGrThreadedRunnable : public SkRunnable { +public: + SkpSkGrThreadedRunnable(void (*testFun)(SkpSkGrThreadState*), int dirNo, const char* str, + SkpSkGrThreadedTestRunner* runner) { + SkASSERT(strlen(str) < sizeof(fState.fResult.fFilename) - 1); + fState.init(dirNo); + strcpy(fState.fResult.fFilename, str); + fState.fReporter = runner->fReporter; + fTestFun = testFun; + } + + virtual void run() SK_OVERRIDE { + SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024); + (*fTestFun)(&fState); + } + + SkpSkGrThreadState fState; + void (*fTestFun)(SkpSkGrThreadState*); +}; + +SkpSkGrThreadedTestRunner::~SkpSkGrThreadedTestRunner() { + for (int index = 0; index < fRunnables.count(); index++) { + SkDELETE(fRunnables[index]); + } +} + +void SkpSkGrThreadedTestRunner::render() { + SkThreadPool pool(fNumThreads); + for (int index = 0; index < fRunnables.count(); ++ index) { + pool.add(fRunnables[index]); + } +} + +//////////////////////////////////////////////// + +static const char outGrDir[] = OUT_DIR "grTest"; +static const char outSkDir[] = OUT_DIR "skTest"; +static const char outSkpDir[] = OUT_DIR "skpTest"; +static const char outDiffDir[] = OUT_DIR "outTest"; +static const char outStatusDir[] = OUT_DIR "statusTest"; + +static SkString make_filepath(int dirIndex, const char* dir, const char* name) { + SkString path(dir); + if (dirIndex) { + path.appendf("%d", dirIndex); + } + path.append(PATH_SLASH); + path.append(name); + return path; +} + +static SkString make_in_dir_name(int dirIndex) { + SkString dirName(IN_DIR); + dirName.appendf("%d", dirIndex); + if (!sk_exists(dirName.c_str())) { + SkDebugf("could not read dir %s\n", dirName.c_str()); + return SkString(); + } + return dirName; +} + +static bool make_out_dirs() { + SkString outDir = make_filepath(0, OUT_DIR, ""); + if (!sk_exists(outDir.c_str())) { + if (!sk_mkdir(outDir.c_str())) { + SkDebugf("could not create dir %s\n", outDir.c_str()); + return false; + } + } + SkString grDir = make_filepath(0, outGrDir, ""); + if (!sk_exists(grDir.c_str())) { + if (!sk_mkdir(grDir.c_str())) { + SkDebugf("could not create dir %s\n", grDir.c_str()); + return false; + } + } + SkString skDir = make_filepath(0, outSkDir, ""); + if (!sk_exists(skDir.c_str())) { + if (!sk_mkdir(skDir.c_str())) { + SkDebugf("could not create dir %s\n", skDir.c_str()); + return false; + } + } + SkString skpDir = make_filepath(0, outSkpDir, ""); + if (!sk_exists(skpDir.c_str())) { + if (!sk_mkdir(skpDir.c_str())) { + SkDebugf("could not create dir %s\n", skpDir.c_str()); + return false; + } + } + SkString diffDir = make_filepath(0, outDiffDir, ""); + if (!sk_exists(diffDir.c_str())) { + if (!sk_mkdir(diffDir.c_str())) { + SkDebugf("could not create dir %s\n", diffDir.c_str()); + return false; + } + } + SkString statusDir = make_filepath(0, outStatusDir, ""); + if (!sk_exists(statusDir.c_str())) { + if (!sk_mkdir(statusDir.c_str())) { + SkDebugf("could not create dir %s\n", statusDir.c_str()); + return false; + } + } + return true; +} + +static SkString make_png_name(const char* filename) { + SkString pngName = SkString(filename); + pngName.remove(pngName.size() - 3, 3); + pngName.append("png"); + return pngName; +} + +typedef GrContextFactory::GLContextType GLContextType; +#ifdef SK_BUILD_FOR_WIN +static const GLContextType kAngle = GrContextFactory::kANGLE_GLContextType; +#else +static const GLContextType kNative = GrContextFactory::kNative_GLContextType; +#endif + +static int similarBits(const SkBitmap& gr, const SkBitmap& sk) { + const int kRowCount = 3; + const int kThreshold = 3; + int width = SkTMin(gr.width(), sk.width()); + if (width < kRowCount) { + return true; + } + int height = SkTMin(gr.height(), sk.height()); + if (height < kRowCount) { + return true; + } + int errorTotal = 0; + SkTArray<char, true> errorRows; + errorRows.push_back_n(width * kRowCount); + SkAutoLockPixels autoGr(gr); + SkAutoLockPixels autoSk(sk); + char* base = &errorRows[0]; + for (int y = 0; y < height; ++y) { + SkPMColor* grRow = gr.getAddr32(0, y); + SkPMColor* skRow = sk.getAddr32(0, y); + char* cOut = &errorRows[(y % kRowCount) * width]; + for (int x = 0; x < width; ++x) { + SkPMColor grColor = grRow[x]; + SkPMColor skColor = skRow[x]; + int dr = SkGetPackedR32(grColor) - SkGetPackedR32(skColor); + int dg = SkGetPackedG32(grColor) - SkGetPackedG32(skColor); + int db = SkGetPackedB32(grColor) - SkGetPackedB32(skColor); + int error = SkTMax(SkAbs32(dr), SkTMax(SkAbs32(dg), SkAbs32(db))); + if ((cOut[x] = error >= kThreshold) && x >= 2 + && base[x - 2] && base[width + x - 2] && base[width * 2 + x - 2] + && base[x - 1] && base[width + x - 1] && base[width * 2 + x - 1] + && base[x - 0] && base[width + x - 0] && base[width * 2 + x - 0]) { + errorTotal += error; + } + } + } + return errorTotal; +} + +static bool addError(SkpSkGrThreadState* data) { + bool foundSmaller = false; + int dCount = data->fFoundCount; + int pixelError = data->fResult.fPixelError; + if (data->fFoundCount < kMaxFiles) { + data->fError[dCount] = pixelError; + strcpy(data->fFilesFound[dCount], data->fResult.fFilename); + data->fDirsFound[dCount] = data->fResult.fDirNo; + ++data->fFoundCount; + } else if (pixelError > data->fSmallestError) { + int smallest = SK_MaxS32; + int smallestIndex = 0; + for (int index = 0; index < kMaxFiles; ++index) { + if (smallest > data->fError[index]) { + smallest = data->fError[index]; + smallestIndex = index; + } + } + data->fError[smallestIndex] = pixelError; + strcpy(data->fFilesFound[smallestIndex], data->fResult.fFilename); + data->fDirsFound[smallestIndex] = data->fResult.fDirNo; + data->fSmallestError = SK_MaxS32; + for (int index = 0; index < kMaxFiles; ++index) { + if (data->fSmallestError > data->fError[index]) { + data->fSmallestError = data->fError[index]; + } + } + SkDebugf("*%d*", data->fSmallestError); + foundSmaller = true; + } + return foundSmaller; +} + +static SkMSec timePict(SkPicture* pic, SkCanvas* canvas) { + canvas->save(); + int pWidth = pic->width(); + int pHeight = pic->height(); + const int maxDimension = 1000; + const int slices = 3; + int xInterval = SkTMax(pWidth - maxDimension, 0) / (slices - 1); + int yInterval = SkTMax(pHeight - maxDimension, 0) / (slices - 1); + SkRect rect = {0, 0, SkIntToScalar(SkTMin(maxDimension, pWidth)), + SkIntToScalar(SkTMin(maxDimension, pHeight))}; + canvas->clipRect(rect); + SkMSec start = SkTime::GetMSecs(); + for (int x = 0; x < slices; ++x) { + for (int y = 0; y < slices; ++y) { + pic->draw(canvas); + canvas->translate(0, SkIntToScalar(yInterval)); + } + canvas->translate(SkIntToScalar(xInterval), SkIntToScalar(-yInterval * slices)); + } + SkMSec end = SkTime::GetMSecs(); + canvas->restore(); + return end - start; +} + +static void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) { + canvas->clear(SK_ColorWHITE); + if (scale != 1) { + canvas->save(); + canvas->scale(1.0f / scale, 1.0f / scale); + } + pic->draw(canvas); + if (scale != 1) { + canvas->restore(); + } +} + +static void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) { + SkString outFile = make_filepath(0, outDir, pngName); + if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, + SkImageEncoder::kPNG_Type, 100)) { + SkDebugf("unable to encode gr %s (width=%d height=%d)br \n", pngName, + bitmap.width(), bitmap.height()); + } +} + +void TestResult::testOne() { + SkPicture* pic = NULL; + { + SkString d; + d.printf(" {%d, \"%s\"},", fDirNo, fFilename); + SkString path = make_filepath(fDirNo, IN_DIR, fFilename); + SkFILEStream stream(path.c_str()); + if (!stream.isValid()) { + SkDebugf("invalid stream %s\n", path.c_str()); + goto finish; + } + if (fTestStep == kEncodeFiles) { + size_t length = stream.getLength(); + SkTArray<char, true> bytes; + bytes.push_back_n(length); + stream.read(&bytes[0], length); + stream.rewind(); + SkString wPath = make_filepath(0, outSkpDir, fFilename); + SkFILEWStream wStream(wPath.c_str()); + wStream.write(&bytes[0], length); + wStream.flush(); + } + pic = SkPicture::CreateFromStream(&stream, &SkImageDecoder::DecodeMemory); + if (!pic) { + SkDebugf("unable to decode %s\n", fFilename); + goto finish; + } + int pWidth = pic->width(); + int pHeight = pic->height(); + int pLargerWH = SkTMax(pWidth, pHeight); + GrContextFactory contextFactory; +#ifdef SK_BUILD_FOR_WIN + GrContext* context = contextFactory.get(kAngle); +#else + GrContext* context = contextFactory.get(kNative); +#endif + if (NULL == context) { + SkDebugf("unable to allocate context for %s\n", fFilename); + goto finish; + } + int maxWH = context->getMaxRenderTargetSize(); + int scale = 1; + while (pLargerWH / scale > maxWH) { + scale *= 2; + } + SkBitmap bitmap; + SkIPoint dim; + do { + dim.fX = (pWidth + scale - 1) / scale; + dim.fY = (pHeight + scale - 1) / scale; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, dim.fX, dim.fY); + bool success = bitmap.allocPixels(); + if (success) { + break; + } + SkDebugf("-%d-", scale); + } while ((scale *= 2) < 256); + if (scale >= 256) { + SkDebugf("unable to allocate bitmap for %s (w=%d h=%d) (sw=%d sh=%d)\n", + fFilename, pWidth, pHeight, dim.fX, dim.fY); + goto finish; + } + SkCanvas skCanvas(bitmap); + drawPict(pic, &skCanvas, fScaleOversized ? scale : 1); + GrTextureDesc desc; + desc.fConfig = kSkia8888_GrPixelConfig; + desc.fFlags = kRenderTarget_GrTextureFlagBit; + desc.fWidth = dim.fX; + desc.fHeight = dim.fY; + desc.fSampleCnt = 0; + SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0)); + if (!texture) { + SkDebugf("unable to allocate texture for %s (w=%d h=%d)\n", fFilename, + dim.fX, dim.fY); + goto finish; + } + SkGpuDevice grDevice(context, texture.get()); + SkCanvas grCanvas(&grDevice); + drawPict(pic, &grCanvas, fScaleOversized ? scale : 1); + const SkBitmap& grBitmap = grDevice.accessBitmap(false); + if (fTestStep == kCompareBits) { + fPixelError = similarBits(grBitmap, bitmap); + int skTime = timePict(pic, &skCanvas); + int grTime = timePict(pic, &grCanvas); + fTime = skTime - grTime; + } else if (fTestStep == kEncodeFiles) { + SkString pngStr = make_png_name(fFilename); + const char* pngName = pngStr.c_str(); + writePict(grBitmap, outGrDir, pngName); + writePict(bitmap, outSkDir, pngName); + } + } +finish: + SkDELETE(pic); +} + +static SkString makeStatusString(int dirNo) { + SkString statName; + statName.printf("stats%d.txt", dirNo); + SkString statusFile = make_filepath(0, outStatusDir, statName.c_str()); + return statusFile; +} + +class PreParser { +public: + PreParser(int dirNo) + : fDirNo(dirNo) + , fIndex(0) + , fStatusPath(makeStatusString(dirNo)) { + if (!sk_exists(fStatusPath.c_str())) { + return; + } + SkFILEStream reader; + reader.setPath(fStatusPath.c_str()); + while (fetch(reader, &fResults.push_back())) + ; + fResults.pop_back(); + } + + bool fetch(SkFILEStream& reader, TestResult* result) { + char c; + int i = 0; + result->init(fDirNo); + result->fPixelError = 0; + result->fTime = 0; + do { + bool readOne = reader.read(&c, 1) != 0; + if (!readOne) { + SkASSERT(i == 0); + return false; + } + if (c == ' ') { + result->fFilename[i++] = '\0'; + break; + } + result->fFilename[i++] = c; + SkASSERT(i < kMaxLength); + } while (true); + do { + SkAssertResult(reader.read(&c, 1) != 0); + if (c == ' ') { + break; + } + SkASSERT(c >= '0' && c <= '9'); + result->fPixelError = result->fPixelError * 10 + (c - '0'); + } while (true); + bool minus = false; + do { + if (reader.read(&c, 1) == 0) { + break; + } + if (c == '\r' && reader.read(&c, 1) == 0) { + break; + } + if (c == '\n') { + break; + } + if (c == '-') { + minus = true; + continue; + } + SkASSERT(c >= '0' && c <= '9'); + result->fTime = result->fTime * 10 + (c - '0'); + } while (true); + if (minus) { + result->fTime = -result->fTime; + } + return true; + } + + bool match(const SkString& filename, SkFILEWStream* stream, TestResult* result) { + if (fIndex < fResults.count()) { + *result = fResults[fIndex++]; + SkASSERT(filename.equals(result->fFilename)); + SkString outStr(result->status()); + stream->write(outStr.c_str(), outStr.size()); + stream->flush(); + return true; + } + return false; + } + +private: + int fDirNo; + int fIndex; + SkTArray<TestResult, true> fResults; + SkString fStatusPath; +}; + +static bool initTest() { +#if !defined SK_BUILD_FOR_WIN && !defined SK_BUILD_FOR_MAC + SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true); + SK_CONF_SET("images.png.suppressDecoderWarnings", true); +#endif + return make_out_dirs(); +} + +static void SkpSkGrTest(skiatest::Reporter* reporter) { + SkTArray<TestResult, true> errors; + if (!initTest()) { + return; + } + SkpSkGrThreadState state; + state.init(0); + int smallCount = 0; + for (int dirNo = 1; dirNo <= 100; ++dirNo) { + SkString pictDir = make_in_dir_name(dirNo); + SkASSERT(pictDir.size()); + if (reporter->verbose()) { + SkDebugf("dirNo=%d\n", dirNo); + } + SkOSFile::Iter iter(pictDir.c_str(), "skp"); + SkString filename; + int testCount = 0; + PreParser preParser(dirNo); + SkFILEWStream statusStream(makeStatusString(dirNo).c_str()); + while (iter.next(&filename)) { + for (size_t index = 0; index < skipOverSkGrCount; ++index) { + if (skipOverSkGr[index].directory == dirNo + && strcmp(filename.c_str(), skipOverSkGr[index].filename) == 0) { + goto skipOver; + } + } + if (preParser.match(filename, &statusStream, &state.fResult)) { + addError(&state); + ++testCount; + goto checkEarlyExit; + } + if (state.fSmallestError > 5000000) { + goto breakOut; + } + { + TestResult& result = state.fResult; + result.test(dirNo, filename); + SkString outStr(result.status()); + statusStream.write(outStr.c_str(), outStr.size()); + statusStream.flush(); + if (1) { + SkDebugf("%s", outStr.c_str()); + } + bool noMatch = addError(&state); + if (noMatch) { + smallCount = 0; + } else if (++smallCount > 10000) { + goto breakOut; + } + } + ++testCount; + if (reporter->verbose()) { + if (testCount % 100 == 0) { + SkDebugf("#%d\n", testCount); + } + } + skipOver: + reporter->bumpTestCount(); + checkEarlyExit: + if (1 && testCount == 20) { + break; + } + } + } +breakOut: + if (reporter->verbose()) { + for (int index = 0; index < state.fFoundCount; ++index) { + SkDebugf("%d %s %d\n", state.fDirsFound[index], state.fFilesFound[index], + state.fError[index]); + } + } + for (int index = 0; index < state.fFoundCount; ++index) { + TestResult::Test(state.fDirsFound[index], state.fFilesFound[index], kEncodeFiles, + reporter->verbose()); + if (reporter->verbose()) SkDebugf("+"); + } +} + +static void bumpCount(skiatest::Reporter* reporter, bool skipping) { + if (reporter->verbose()) { + static int threadTestCount; + sk_atomic_inc(&threadTestCount); + if (!skipping && threadTestCount % 100 == 0) { + SkDebugf("#%d\n", threadTestCount); + } + if (skipping && threadTestCount % 10000 == 0) { + SkDebugf("#%d\n", threadTestCount); + } + } +} + +static void testSkGrMain(SkpSkGrThreadState* data) { + data->fResult.testOne(); + bumpCount(data->fReporter, false); + data->fReporter->bumpTestCount(); +} + +static void SkpSkGrThreadedTest(skiatest::Reporter* reporter) { + if (!initTest()) { + return; + } + int threadCount = reporter->allowThreaded() ? 3 : 1; + SkpSkGrThreadedTestRunner testRunner(reporter, threadCount); + for (int dirIndex = 1; dirIndex <= 100; ++dirIndex) { + SkString pictDir = make_in_dir_name(dirIndex); + if (pictDir.size() == 0) { + continue; + } + SkOSFile::Iter iter(pictDir.c_str(), "skp"); + SkString filename; + while (iter.next(&filename)) { + SkString pngName = make_png_name(filename.c_str()); + SkString oldPng = make_filepath(dirIndex, outSkDir, pngName.c_str()); + SkString newPng = make_filepath(dirIndex, outGrDir, pngName.c_str()); + if (sk_exists(oldPng.c_str()) && sk_exists(newPng.c_str())) { + bumpCount(reporter, true); + continue; + } + for (size_t index = 0; index < skipOverSkGrCount; ++index) { + if (skipOverSkGr[index].directory == dirIndex + && strcmp(filename.c_str(), skipOverSkGr[index].filename) == 0) { + bumpCount(reporter, true); + goto skipOver; + } + } + *testRunner.fRunnables.append() = SkNEW_ARGS(SkpSkGrThreadedRunnable, + (&testSkGrMain, dirIndex, filename.c_str(), &testRunner)); + skipOver: + ; + } + } + testRunner.render(); + SkpSkGrThreadState& max = testRunner.fRunnables[0]->fState; + for (int dirIndex = 2; dirIndex <= 100; ++dirIndex) { + SkpSkGrThreadState& state = testRunner.fRunnables[dirIndex - 1]->fState; + for (int index = 0; index < state.fFoundCount; ++index) { + int maxIdx = max.fFoundCount; + if (maxIdx < kMaxFiles) { + max.fError[maxIdx] = state.fError[index]; + strcpy(max.fFilesFound[maxIdx], state.fFilesFound[index]); + max.fDirsFound[maxIdx] = state.fDirsFound[index]; + ++max.fFoundCount; + continue; + } + for (maxIdx = 0; maxIdx < max.fFoundCount; ++maxIdx) { + if (max.fError[maxIdx] < state.fError[index]) { + max.fError[maxIdx] = state.fError[index]; + strcpy(max.fFilesFound[maxIdx], state.fFilesFound[index]); + max.fDirsFound[maxIdx] = state.fDirsFound[index]; + break; + } + } + } + } + TestResult encoder; + encoder.fTestStep = kEncodeFiles; + for (int index = 0; index < max.fFoundCount; ++index) { + encoder.fDirNo = max.fDirsFound[index]; + strcpy(encoder.fFilename, max.fFilesFound[index]); + encoder.testOne(); + SkDebugf("+"); + } +} + +static void SkpSkGrOneOffTest(skiatest::Reporter* reporter) { + if (!initTest()) { + return; + } + int testIndex = 166; + int dirIndex = skipOverSkGr[testIndex - 166].directory; + SkString pictDir = make_in_dir_name(dirIndex); + if (pictDir.size() == 0) { + return; + } + SkString filename(skipOverSkGr[testIndex - 166].filename); + TestResult::Test(dirIndex, filename.c_str(), kCompareBits, reporter->verbose()); + TestResult::Test(dirIndex, filename.c_str(), kEncodeFiles, reporter->verbose()); +} + +#include "TestClassDef.h" +DEFINE_TESTCLASS_SHORT(SkpSkGrTest) + +DEFINE_TESTCLASS_SHORT(SkpSkGrOneOffTest) + +DEFINE_TESTCLASS_SHORT(SkpSkGrThreadedTest) |