aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-11-01 17:36:03 +0000
committerGravatar caryclark@google.com <caryclark@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-11-01 17:36:03 +0000
commita2bbc6e19d5332e81784e582c290cc060f40c4c7 (patch)
tree507a82e41b5a59f261295718091f0f1491b3d894 /tests
parent045c3d330c6c14f090c2222ece08d82cb84fb3ea (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.cpp12
-rw-r--r--tests/PathOpsCubicLineIntersectionTest.cpp3
-rw-r--r--tests/PathOpsCubicQuadIntersectionTest.cpp24
-rw-r--r--tests/PathOpsDQuadTest.cpp15
-rw-r--r--tests/PathOpsDTriangleTest.cpp30
-rw-r--r--tests/PathOpsExtendedTest.cpp5
-rw-r--r--tests/PathOpsOpTest.cpp36
-rw-r--r--tests/PathOpsQuadIntersectionTest.cpp3
-rw-r--r--tests/PathOpsQuadLineIntersectionTest.cpp7
-rwxr-xr-xtests/PathOpsSkpClipTest.cpp807
-rwxr-xr-xtests/PathOpsSkpTest.cpp924
-rw-r--r--tests/PathOpsThreadedCommon.h9
-rwxr-xr-xtests/PathOpsTypesTest.cpp24
-rwxr-xr-xtests/SkpSkGrTest.cpp759
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)