10a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
27839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkBitmap.h"
37839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkCanvas.h"
40a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkColor.h"
50a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkColorPriv.h"
60a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkDevice.h"
70a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkGraphics.h"
858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkImageDecoder.h"
97839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkImageEncoder.h"
107839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkOSFile.h"
110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkPathOpsDebug.h"
127839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkPicture.h"
130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkRTConf.h"
140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkStream.h"
157839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "SkString.h"
160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkTArray.h"
170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkTDArray.h"
180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkThreadPool.h"
190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "SkTime.h"
200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#include "Test.h"
2158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
2258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#ifdef SK_BUILD_FOR_WIN
230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #define PATH_SLASH "\\"
240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #define IN_DIR "D:\\9-30-13\\"
250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #define OUT_DIR "D:\\opSkpClip\\1\\"
2658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#else
270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #define PATH_SLASH "/"
280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #ifdef SK_BUILD_FOR_MAC
290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        #define IN_DIR "/Volumes/tera/9-30-13/skp"
300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        #define OUT_DIR "/Volumes/tera/out/9-30-13/1/"
310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #else
320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        #define IN_DIR "/usr/local/google/home/caryclark/skps/9-30-13/skp"
330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        #define OUT_DIR "/mnt/skia/opSkpClip/1/"
340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #endif
3558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#endif
3658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerconst struct {
380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int directory;
390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const char* filename;
400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger} skipOverSept[] = {
410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    {9, "http___www_symptome_ch_.skp"}, // triangle clip with corner at x.999
420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    {11, "http___www_menly_fr_.skp"},
430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    {12, "http___www_banrasdr_com_.skp"},
440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
457839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergersize_t skipOverSeptCount = sizeof(skipOverSept) / sizeof(skipOverSept[0]);
470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerenum TestStep {
490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    kCompareBits,
500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    kEncodeFiles,
510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerenum {
540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    kMaxLength = 128,
550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    kMaxFiles = 128,
560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    kSmallLimit = 1000,
570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstruct TestResult {
600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void init(int dirNo) {
610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fDirNo = dirNo;
620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        sk_bzero(fFilename, sizeof(fFilename));
630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fTestStep = kCompareBits;
640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fScaleOversized = true;
657839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
667839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString status() {
680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkString outStr;
690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        outStr.printf("%s %d %d\n", fFilename, fPixelError, fTime);
700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return outStr;
7158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static void Test(int dirNo, const char* filename, TestStep testStep) {
740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        TestResult test;
750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        test.init(dirNo);
760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        test.fTestStep = testStep;
770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        strcpy(test.fFilename, filename);
780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        test.testOne();
7958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void test(int dirNo, const SkString& filename) {
820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        init(dirNo);
830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        strcpy(fFilename, filename.c_str());
840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        testOne();
8558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void testOne();
880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    char fFilename[kMaxLength];
900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestStep fTestStep;
910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fDirNo;
920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fPixelError;
930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fTime;
940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool fScaleOversized;
950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstruct TestState {
980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void init(int dirNo, skiatest::Reporter* reporter) {
990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fReporter = reporter;
1000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fResult.init(dirNo);
1010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fFoundCount = 0;
1020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        TestState::fSmallCount = 0;
1030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fSmallestError = 0;
1040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        sk_bzero(fFilesFound, sizeof(fFilesFound));
1050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        sk_bzero(fDirsFound, sizeof(fDirsFound));
1060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        sk_bzero(fError, sizeof(fError));
10758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
1080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static bool bumpSmallCount() {
1100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        sk_atomic_inc(&fSmallCount);
1110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return fSmallCount > kSmallLimit;
11258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
1130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static void clearSmallCount() {
1150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (fSmallCount < kSmallLimit) {
1160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fSmallCount = 0;
1170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
1180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    char fFilesFound[kMaxFiles][kMaxLength];
1210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fDirsFound[kMaxFiles];
1220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fError[kMaxFiles];
1230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fFoundCount;
1240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    static int fSmallCount;
1250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fSmallestError;
1260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    skiatest::Reporter* fReporter;
1270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestResult fResult;
1280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
1290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerint TestState::fSmallCount;
1310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstruct TestRunner {
1330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestRunner(skiatest::Reporter* reporter, int threadCount)
1340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        : fNumThreads(threadCount)
1350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        , fReporter(reporter) {
1360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    ~TestRunner();
1390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void render();
1400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fNumThreads;
1410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkTDArray<class TestRunnable*> fRunnables;
1420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    skiatest::Reporter* fReporter;
1430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
1440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass TestRunnable : public SkRunnable {
1460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerpublic:
1470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestRunnable(void (*testFun)(TestState*), int dirNo, TestRunner* runner) {
1480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fState.init(dirNo, runner->fReporter);
1490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fTestFun = testFun;
1500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    virtual void run() SK_OVERRIDE {
1530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024);
1540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        (*fTestFun)(&fState);
15558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
1560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestState fState;
1580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    void (*fTestFun)(TestState*);
1590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
1600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1610a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerTestRunner::~TestRunner() {
1620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int index = 0; index < fRunnables.count(); index++) {
1630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDELETE(fRunnables[index]);
1640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
1660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergervoid TestRunner::render() {
1680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkThreadPool pool(fNumThreads);
1690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int index = 0; index < fRunnables.count(); ++ index) {
1700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        pool.add(fRunnables[index]);
1710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
1730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger////////////////////////////////////////////////
1750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic const char outOpDir[] = OUT_DIR "opClip";
1770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic const char outOldDir[] = OUT_DIR "oldClip";
1780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic const char outSkpDir[] = OUT_DIR "skpTest";
1790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic const char outDiffDir[] = OUT_DIR "outTest";
1800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic const char outStatusDir[] = OUT_DIR "statusTest";
1810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic SkString make_filepath(int dirNo, const char* dir, const char* name) {
1830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString path(dir);
1840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (dirNo) {
1850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        path.appendf("%d", dirNo);
1860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    path.append(PATH_SLASH);
1880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    path.append(name);
1890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return path;
1900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
1910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
1920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic SkString make_in_dir_name(int dirNo) {
1930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString dirName(IN_DIR);
1940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    dirName.appendf("%d", dirNo);
1950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (!sk_exists(dirName.c_str())) {
1960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf("could not read dir %s\n", dirName.c_str());
1970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return SkString();
1980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
1990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return dirName;
2000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
2010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
2020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic bool make_one_out_dir(const char* outDirStr) {
2030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString outDir = make_filepath(0, outDirStr, "");
2040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (!sk_exists(outDir.c_str())) {
2050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!sk_mkdir(outDir.c_str())) {
2060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf("could not create dir %s\n", outDir.c_str());
2070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return false;
2080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
2090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
2100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return true;
2110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
2120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
2130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic bool make_out_dirs() {
2140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString outDir = make_filepath(0, OUT_DIR, "");
2150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (!sk_exists(outDir.c_str())) {
2160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!sk_mkdir(outDir.c_str())) {
2170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf("could not create dir %s\n", outDir.c_str());
2180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return false;
2190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
2200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
2210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return make_one_out_dir(outOldDir)
2220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            && make_one_out_dir(outOpDir)
2230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            && make_one_out_dir(outSkpDir)
2240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            && make_one_out_dir(outDiffDir)
2250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            && make_one_out_dir(outStatusDir);
2260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
2270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
2280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic SkString make_png_name(const char* filename) {
2290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString pngName = SkString(filename);
23058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    pngName.remove(pngName.size() - 3, 3);
23158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    pngName.append("png");
2320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return pngName;
2330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
2340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
2350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic int similarBits(const SkBitmap& gr, const SkBitmap& sk) {
2360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const int kRowCount = 3;
2370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const int kThreshold = 3;
2380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int width = SkTMin(gr.width(), sk.width());
2390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (width < kRowCount) {
2400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return true;
2410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
2420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int height = SkTMin(gr.height(), sk.height());
2430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (height < kRowCount) {
2440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return true;
2450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
2460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int errorTotal = 0;
2470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkTArray<int, true> errorRows;
2480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    errorRows.push_back_n(width * kRowCount);
2490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkAutoLockPixels autoGr(gr);
2500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkAutoLockPixels autoSk(sk);
2510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int y = 0; y < height; ++y) {
2520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkPMColor* grRow = gr.getAddr32(0, y);
2530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkPMColor* skRow = sk.getAddr32(0, y);
2540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int* base = &errorRows[0];
2550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int* cOut = &errorRows[y % kRowCount];
2560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (int x = 0; x < width; ++x) {
2570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkPMColor grColor = grRow[x];
2580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkPMColor skColor = skRow[x];
2590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int dr = SkGetPackedR32(grColor) - SkGetPackedR32(skColor);
2600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int dg = SkGetPackedG32(grColor) - SkGetPackedG32(skColor);
2610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int db = SkGetPackedB32(grColor) - SkGetPackedB32(skColor);
2620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int error = cOut[x] = SkTMax(SkAbs32(dr), SkTMax(SkAbs32(dg), SkAbs32(db)));
2630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (error < kThreshold || x < 2) {
2640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                continue;
2650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
2660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (base[x - 2] < kThreshold
2670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    || base[width + x - 2] < kThreshold
2680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    || base[width * 2 + x - 2] < kThreshold
2690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    || base[x - 1] < kThreshold
2700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    || base[width + x - 1] < kThreshold
2710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    || base[width * 2 + x - 1] < kThreshold
2720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    || base[x] < kThreshold
2730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    || base[width + x] < kThreshold
2740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    || base[width * 2 + x] < kThreshold) {
2750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                continue;
2760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
2770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            errorTotal += error;
2780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
2790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
2800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return errorTotal;
2810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
2820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
2830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic bool addError(TestState* data, const TestResult& testResult) {
2840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool foundSmaller = false;
2850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int dCount = data->fFoundCount;
2860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int pixelError = testResult.fPixelError;
2870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (data->fFoundCount < kMaxFiles) {
2880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        data->fError[dCount] = pixelError;
2890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        strcpy(data->fFilesFound[dCount], testResult.fFilename);
2900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        data->fDirsFound[dCount] = testResult.fDirNo;
2910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        ++data->fFoundCount;
2920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    } else if (pixelError > data->fSmallestError) {
2930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int smallest = SK_MaxS32;
2940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int smallestIndex = 0;
2950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (int index = 0; index < kMaxFiles; ++index) {
2960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (smallest > data->fError[index]) {
2970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                smallest = data->fError[index];
2980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                smallestIndex = index;
2990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
3000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
3010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        data->fError[smallestIndex] = pixelError;
3020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        strcpy(data->fFilesFound[smallestIndex], testResult.fFilename);
3030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        data->fDirsFound[smallestIndex] = testResult.fDirNo;
3040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        data->fSmallestError = SK_MaxS32;
3050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (int index = 0; index < kMaxFiles; ++index) {
3060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (data->fSmallestError > data->fError[index]) {
3070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                data->fSmallestError = data->fError[index];
3080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
3090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
3100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf("*%d*", data->fSmallestError);
3110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        foundSmaller = true;
3120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
3130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return foundSmaller;
3140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
3150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic SkMSec timePict(SkPicture* pic, SkCanvas* canvas) {
3190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    canvas->save();
3200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int pWidth = pic->width();
3210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int pHeight = pic->height();
3220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const int maxDimension = 1000;
3230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const int slices = 3;
3240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int xInterval = SkTMax(pWidth - maxDimension, 0) / (slices - 1);
3250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int yInterval = SkTMax(pHeight - maxDimension, 0) / (slices - 1);
3260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkRect rect = {0, 0, SkIntToScalar(SkTMin(maxDimension, pWidth)),
3270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkIntToScalar(SkTMin(maxDimension, pHeight))};
3280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    canvas->clipRect(rect);
3290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkMSec start = SkTime::GetMSecs();
3300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int x = 0; x < slices; ++x) {
3310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (int y = 0; y < slices; ++y) {
3320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            pic->draw(canvas);
3330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            canvas->translate(0, SkIntToScalar(yInterval));
3340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
3350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        canvas->translate(SkIntToScalar(xInterval), SkIntToScalar(-yInterval * slices));
3360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
3370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkMSec end = SkTime::GetMSecs();
3380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    canvas->restore();
3390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return end - start;
3400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
3410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) {
3430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    canvas->clear(SK_ColorWHITE);
3440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (scale != 1) {
3450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        canvas->save();
3460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        canvas->scale(1.0f / scale, 1.0f / scale);
34758190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    }
3480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    pic->draw(canvas);
3490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (scale != 1) {
3500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        canvas->restore();
3510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
3520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
3530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) {
3550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString outFile = make_filepath(0, outDir, pngName);
3560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap,
3570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkImageEncoder::kPNG_Type, 100)) {
3580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf("unable to encode gr %s (width=%d height=%d)\n", pngName,
3590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    bitmap.width(), bitmap.height());
3600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
3610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
3620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
3630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergervoid TestResult::testOne() {
3640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkPicture* pic = NULL;
3650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    {
3660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #if DEBUG_SHOW_TEST_NAME
3670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (fTestStep == kCompareBits) {
3680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkString testName(fFilename);
3690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            const char http[] = "http";
3700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (testName.startsWith(http)) {
3710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                testName.remove(0, sizeof(http) - 1);
3720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
3730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            while (testName.startsWith("_")) {
3740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                testName.remove(0, 1);
3750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
3760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            const char dotSkp[] = ".skp";
3770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (testName.endsWith(dotSkp)) {
3780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                size_t len = testName.size();
3790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                testName.remove(len - (sizeof(dotSkp) - 1), sizeof(dotSkp) - 1);
3800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
3810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            testName.prepend("skp");
3820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            testName.append("1");
3830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            strncpy(DEBUG_FILENAME_STRING, testName.c_str(), DEBUG_FILENAME_STRING_LENGTH);
3840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        } else if (fTestStep == kEncodeFiles) {
3850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            strncpy(DEBUG_FILENAME_STRING, "", DEBUG_FILENAME_STRING_LENGTH);
3860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
3870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    #endif
3880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkString path = make_filepath(fDirNo, IN_DIR, fFilename);
3890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkFILEStream stream(path.c_str());
3900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!stream.isValid()) {
3910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf("invalid stream %s\n", path.c_str());
3920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            goto finish;
3930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
3940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkPicture* pic = SkPicture::CreateFromStream(&stream, &SkImageDecoder::DecodeMemory);
3950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!pic) {
3960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf("unable to decode %s\n", fFilename);
3970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            goto finish;
3980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
3990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int width = pic->width();
4000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int height = pic->height();
4010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkBitmap oldBitmap, opBitmap;
4020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int scale = 1;
4030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        do {
4040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int dimX = (width + scale - 1) / scale;
4050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int dimY = (height + scale - 1) / scale;
4060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            oldBitmap.setConfig(SkBitmap::kARGB_8888_Config, dimX, dimY);
4070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            opBitmap.setConfig(SkBitmap::kARGB_8888_Config, dimX, dimY);
4080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            bool success = oldBitmap.allocPixels() && opBitmap.allocPixels();
4090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (success) {
4100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                break;
4110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
4120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf("-%d-", scale);
4130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        } while ((scale *= 2) < 256);
4140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (scale >= 256) {
4150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf("unable to allocate bitmap for %s (w=%d h=%d)\n", fFilename,
4160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    width, height);
4170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return;
4180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
4190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        oldBitmap.eraseColor(SK_ColorWHITE);
4200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkCanvas oldCanvas(oldBitmap);
4210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        oldCanvas.setAllowSimplifyClip(false);
4220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        opBitmap.eraseColor(SK_ColorWHITE);
4230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkCanvas opCanvas(opBitmap);
4240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        opCanvas.setAllowSimplifyClip(true);
4250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        drawPict(pic, &oldCanvas, fScaleOversized ? scale : 1);
4260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        drawPict(pic, &opCanvas, fScaleOversized ? scale : 1);
4270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (fTestStep == kCompareBits) {
4280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fPixelError = similarBits(oldBitmap, opBitmap);
4290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int oldTime = timePict(pic, &oldCanvas);
4300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            int opTime = timePict(pic, &opCanvas);
4310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            fTime = oldTime - opTime;
4320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        } else if (fTestStep == kEncodeFiles) {
4330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkString pngStr = make_png_name(fFilename);
4340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            const char* pngName = pngStr.c_str();
4350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            writePict(oldBitmap, outOldDir, pngName);
4360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            writePict(opBitmap, outOpDir, pngName);
4370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
4380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
4390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerfinish:
44058190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkDELETE(pic);
44158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
44258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
4430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic SkString makeStatusString(int dirNo) {
4440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString statName;
4450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    statName.printf("stats%d.txt", dirNo);
4460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString statusFile = make_filepath(0, outStatusDir, statName.c_str());
4470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return statusFile;
4480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
44958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
4500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerclass PreParser {
4510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerpublic:
4520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    PreParser(int dirNo)
4530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        : fDirNo(dirNo)
4540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        , fIndex(0) {
4550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkString statusPath = makeStatusString(dirNo);
4560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!sk_exists(statusPath.c_str())) {
4570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return;
4580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
4590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkFILEStream reader;
4600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        reader.setPath(statusPath.c_str());
4610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        while (fetch(reader, &fResults.push_back()))
4620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            ;
4630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        fResults.pop_back();
4640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
4650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
4660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool fetch(SkFILEStream& reader, TestResult* result) {
4670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        char c;
4680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        int i = 0;
4690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        result->init(fDirNo);
4700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        result->fPixelError = 0;
4710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        result->fTime = 0;
4720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        do {
4730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            bool readOne = reader.read(&c, 1) != 0;
4740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (!readOne) {
4750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                SkASSERT(i == 0);
4760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                return false;
4770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
4780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (c == ' ') {
4790a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                result->fFilename[i++] = '\0';
4800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                break;
4810a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
4820a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            result->fFilename[i++] = c;
4830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkASSERT(i < kMaxLength);
4840a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        } while (true);
4850a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        do {
4860a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkAssertResult(reader.read(&c, 1));
4870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (c == ' ') {
4880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                break;
4890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
4900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkASSERT(c >= '0' && c <= '9');
4910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            result->fPixelError = result->fPixelError * 10 + (c - '0');
4920a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        } while (true);
4930a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        bool minus = false;
4940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        do {
4950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkAssertResult(reader.read(&c, 1));
4960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (c == '\n') {
4970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                break;
4980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
4990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (c == '-') {
5000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                minus = true;
5010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                continue;
5020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
5030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkASSERT(c >= '0' && c <= '9');
5040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            result->fTime = result->fTime * 10 + (c - '0');
5050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        } while (true);
5060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (minus) {
5070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            result->fTime = -result->fTime;
5080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
5090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return true;
5100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
5110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
5120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    bool match(const SkString& filename, SkFILEWStream* stream, TestResult* result) {
5130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (fIndex < fResults.count()) {
5140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            *result = fResults[fIndex++];
5150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkASSERT(filename.equals(result->fFilename));
5160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkString outStr(result->status());
5170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            stream->write(outStr.c_str(), outStr.size());
5180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return true;
5190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
5200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return false;
5210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
5220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
5230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerprivate:
5240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fDirNo;
5250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int fIndex;
5260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkTArray<TestResult, true> fResults;
5270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger};
5280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
5290a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic bool doOneDir(TestState* state) {
5300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int dirNo = state->fResult.fDirNo;
5310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    skiatest::Reporter* reporter = state->fReporter;
5320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString dirName = make_in_dir_name(dirNo);
5330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkASSERT(dirName.size());
5340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkOSFile::Iter iter(dirName.c_str(), "skp");
5357839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    SkString filename;
53658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    int testCount = 0;
5370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    PreParser preParser(dirNo);
5380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkFILEWStream statusStream(makeStatusString(dirNo).c_str());
5397839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    while (iter.next(&filename)) {
5400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (size_t index = 0; index < skipOverSeptCount; ++index) {
5410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (skipOverSept[index].directory == dirNo
5420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                    && strcmp(filename.c_str(), skipOverSept[index].filename) == 0) {
5430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                goto skipOver;
5440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
5450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
5460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (preParser.match(filename, &statusStream, &state->fResult)) {
5470a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            addError(state, state->fResult);
5480a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            ++testCount;
5490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            goto checkEarlyExit;
5500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
5510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (state->fSmallestError > 5000000) {
5520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return false;
5530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
5540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        {
5550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            TestResult& result = state->fResult;
5560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            result.test(dirNo, filename);
5570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkString outStr(result.status());
5580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            statusStream.write(outStr.c_str(), outStr.size());
5590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            statusStream.flush();
5600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (1) {
5610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                SkDebugf("%s", outStr.c_str());
5620a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
5630a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            bool noMatch = addError(state, state->fResult);
5640a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            if (noMatch) {
5650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                state->clearSmallCount();
5660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            } else if (state->bumpSmallCount()) {
5670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                return false;
5680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            }
5697839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
5700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        ++testCount;
57158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        if (reporter->verbose()) {
57258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            SkDebugf(".");
57358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            if (++testCount % 100 == 0) {
5740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                SkDebugf("%d\n", testCount);
57558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            }
5767839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
5770a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergerskipOver:
5780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (reporter->verbose()) {
57958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            static int threadTestCount;
5800a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf(".");
58158190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            sk_atomic_inc(&threadTestCount);
58258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            if (threadTestCount % 100 == 0) {
5830a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                SkDebugf("%d\n", threadTestCount);
58458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger            }
5857839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        }
5860a657bbc2c6fc9daf699942e023050536d5ec95fDerek SollenbergercheckEarlyExit:
5870a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (1 && testCount == 20) {
5880a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            return true;
5890a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
5900a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
5910a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return true;
59258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
59358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
5940a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic bool initTest() {
5950a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#if !defined SK_BUILD_FOR_WIN && !defined SK_BUILD_FOR_MAC
5960a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true);
5970a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SK_CONF_SET("images.png.suppressDecoderWarnings", true);
5980a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger#endif
5990a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    return make_out_dirs();
6000a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
6010a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
6020a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void encodeFound(skiatest::Reporter* reporter, TestState& state) {
6030a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (reporter->verbose()) {
6040a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (int index = 0; index < state.fFoundCount; ++index) {
6050a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf("%d %s %d\n", state.fDirsFound[index], state.fFilesFound[index],
6060a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                     state.fError[index]);
6070a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
6080a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6090a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int index = 0; index < state.fFoundCount; ++index) {
6100a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        TestResult::Test(state.fDirsFound[index], state.fFilesFound[index], kEncodeFiles);
6110a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (state.fReporter->verbose()) SkDebugf("+");
6120a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6130a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
6140a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
6150a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void PathOpsSkpClipTest(skiatest::Reporter* reporter) {
6160a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (!initTest()) {
6170a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return;
6180a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6190a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkTArray<TestResult, true> errors;
6200a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestState state;
6210a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    state.init(0, reporter);
6220a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int dirNo = 1; dirNo <= 100; ++dirNo) {
6230a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (reporter->verbose()) {
6240a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkDebugf("dirNo=%d\n", dirNo);
6250a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
6260a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        state.fResult.fDirNo = dirNo;
6270a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        if (!doOneDir(&state)) {
6280a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            break;
62958190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger        }
6300a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6310a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    encodeFound(reporter, state);
6320a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
6330a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
6340a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void testSkpClipMain(TestState* data) {
6350a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        (void) doOneDir(data);
6360a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger}
6370a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger
6380a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenbergerstatic void PathOpsSkpClipThreadedTest(skiatest::Reporter* reporter) {
6390a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (!initTest()) {
6400a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return;
6410a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6420a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int threadCount = reporter->allowThreaded() ? SkThreadPool::kThreadPerCore : 1;
6430a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestRunner testRunner(reporter, threadCount);
6440a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int dirNo = 1; dirNo <= 100; ++dirNo) {
6450a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnable,
6460a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger                (&testSkpClipMain, dirNo, &testRunner));
6477839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
64858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    testRunner.render();
6490a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestState state;
6500a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    state.init(0, reporter);
6510a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    for (int dirNo = 1; dirNo <= 100; ++dirNo) {
6520a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        TestState& testState = testRunner.fRunnables[dirNo - 1]->fState;
6530a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        for (int inner = 0; inner < testState.fFoundCount; ++inner) {
6540a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            TestResult& testResult = testState.fResult;
6550a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            SkASSERT(testResult.fDirNo == dirNo);
6560a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            testResult.fPixelError = testState.fError[inner];
6570a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            strcpy(testResult.fFilename, testState.fFilesFound[inner]);
6580a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger            addError(&state, testResult);
6590a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        }
6600a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6610a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    encodeFound(reporter, state);
66258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger}
66358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
66458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenbergerstatic void PathOpsSkpClipOneOffTest(skiatest::Reporter* reporter) {
6650a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (!initTest()) {
6660a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        return;
6670a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6680a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    const int testIndex = 43 - 41;
6690a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    int dirNo = skipOverSept[testIndex].directory;
6700a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkAssertResult(make_in_dir_name(dirNo).size());
6710a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    SkString filename(skipOverSept[testIndex].filename);
6720a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    TestResult state;
6730a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    state.test(dirNo, filename);
6740a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    if (reporter->verbose()) {
6750a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger        SkDebugf("%s", state.status().c_str());
6760a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    }
6770a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    state.fTestStep = kEncodeFiles;
6780a657bbc2c6fc9daf699942e023050536d5ec95fDerek Sollenberger    state.testOne();
6797839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger}
6807839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
6817839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger#include "TestClassDef.h"
6827839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerDEFINE_TESTCLASS_SHORT(PathOpsSkpClipTest)
68358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
68458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_TESTCLASS_SHORT(PathOpsSkpClipOneOffTest)
68558190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger
68658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek SollenbergerDEFINE_TESTCLASS_SHORT(PathOpsSkpClipThreadedTest)
687