119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#include "CrashHandler.h"
219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark// #include "OverwriteLine.h"
319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#include "Resources.h"
42b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com#include "SkBitmap.h"
5a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkCanvas.h"
67eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com#include "SkColor.h"
7a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkColorPriv.h"
819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#include "SkCommandLineFlags.h"
92b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com#include "SkDevice.h"
1019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#include "SkForceLinking.h"
11a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkGraphics.h"
12cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com#include "SkImageDecoder.h"
132b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com#include "SkImageEncoder.h"
142b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com#include "SkOSFile.h"
15a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkPathOpsDebug.h"
162b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com#include "SkPicture.h"
17a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkRTConf.h"
184431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org#include "SkTSort.h"
19a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkStream.h"
202b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com#include "SkString.h"
21a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkTArray.h"
22a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkTDArray.h"
23406654be7a930b484159f5bca107d3b11d8a9edemtklein#include "SkTaskGroup.h"
2419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#include "SkTemplates.h"
25a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#include "SkTime.h"
2619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
2719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark__SK_FORCE_IMAGE_DECODER_LINKING;
2819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
2919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark/* add local exceptions here */
3019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark/* TODO : add command flag interface */
3119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkconst struct SkipOverTest {
3219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int directory;
3319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const char* filename;
3419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    bool blamePathOps;
3519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark} skipOver[] = {
3619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    { 2, "http___www_groupon_sg_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
3719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    { 6, "http___www_googleventures_com_.skp", true},  // addTCoincident SkASSERT(test->fT < 1);
3819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    { 7, "http___www_foxsports_nl_.skp", true},  // (no repro on mac) addT SkASSERT(this != other || fVerb == SkPath::kCubic_Verb)
3919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {13, "http___www_modernqigong_com_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
4019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {14, "http___www_devbridge_com_.skp", true},  // checkSmallCoincidence SkASSERT(!next->fSmall || checkMultiple);
415e27e0eb1d1d4c7674e221d3ba3314500ea0b97acaryclark    {16, "http___www_1023world_net_.skp", false},  // bitmap decode assert (corrupt skp?)
4219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {19, "http___www_alamdi_com_.skp", true},  // cubic/quad intersection
4319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {26, "http___www_liveencounters_net_.skp", true},  // (no repro on mac) checkSmall addT:549 (line, expects cubic)
4419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {28, "http___www_encros_fr_.skp", false},  // SkAAClip::Builder::addRun SkASSERT(fBounds.contains(x, y));
4519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {37, "http___www_familysurvivalprotocol_wordpress_com_.skp", true},  // bumpSpan SkASSERT(span->fOppValue >= 0);
4619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {39, "http___sufeinet_com_.skp", false}, // bitmap decode assert (corrupt skp?)
4719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {41, "http___www_rano360_com_.skp", true}, // checkSmallCoincidence SkASSERT(!next->fSmall || checkMultiple);
4819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {44, "http___www_firstunitedbank_com_.skp", true},  // addTCancel SkASSERT(oIndex > 0);
4919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {46, "http___www_shinydemos_com_.skp", true},  // addSimpleAngle SkASSERT(index == count() - 2);
5019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {48, "http___www_familysurvivalprotocol_com_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
5119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {57, "http___www_lptemp_com_.skp", true}, // addTCoincident oPeek = &other->fTs[++oPeekIndex];
5219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {71, "http___www_1milyonkahraman_org_.skp", true},  // addTCoincident SkASSERT(test->fT < 1);
5319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {88, "http___www_apuntesdelechuza_wordpress_com_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
5419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {89, "http___www_mobilizedconsulting_com_.skp", true}, // addTCancel SkASSERT(oIndex > 0);
5519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    {93, "http___www_simple_living_in_suffolk_co_uk_.skp", true},  // bumpSpan SkASSERT "span->fOppValue >= 0"
5619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark};
5719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
5819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarksize_t skipOverCount = sizeof(skipOver) / sizeof(skipOver[0]);
5919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
6019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
6119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark/* customize file in/out here */
6219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark/* TODO : add command flag interface */
6319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#define CHROME_VERSION "1e5dfa4-4a995df"
6419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#define SUMMARY_RUN 1
6507e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com
6607e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com#ifdef SK_BUILD_FOR_WIN
6719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    #define DRIVE_SPEC "D:"
687eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com    #define PATH_SLASH "\\"
6907e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com#else
7019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    #define DRIVE_SPEC ""
717eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com    #define PATH_SLASH "/"
7207e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com#endif
7307e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com
7419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#define IN_DIR_PRE  DRIVE_SPEC PATH_SLASH "skps"   PATH_SLASH "slave"
7519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#define OUT_DIR_PRE DRIVE_SPEC PATH_SLASH "skpOut" PATH_SLASH "slave"
7619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#define OUT_DIR_SUM DRIVE_SPEC PATH_SLASH "skpOut" PATH_SLASH "summary"
7719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#define DIR_POST               PATH_SLASH "All"    PATH_SLASH CHROME_VERSION
7819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
7919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic const char outOpDir[]     = "opClip";
8019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic const char outOldDir[]    = "oldClip";
8119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic const char outStatusDir[] = "statusTest";
8219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
8319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic SkString get_in_path(int dirNo, const char* filename) {
8419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString path;
8519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkASSERT(dirNo);
8619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    path.appendf("%s%d%s", IN_DIR_PRE, dirNo, DIR_POST);
8719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!sk_exists(path.c_str())) {
8819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkDebugf("could not read %s\n", path.c_str());
8919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return SkString();
9019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
9119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (filename) {
9219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        path.appendf("%s%s", PATH_SLASH, filename);
93406654be7a930b484159f5bca107d3b11d8a9edemtklein        if (!sk_exists(path.c_str())) {
9419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            SkDebugf("could not read %s\n", path.c_str());
9519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            return SkString();
9619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
9719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
9819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return path;
9919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
100406654be7a930b484159f5bca107d3b11d8a9edemtklein
10119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic void make_recursive_dir(const SkString& path) {
10219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (sk_exists(path.c_str())) {
10319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return;
10419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
10519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const char* pathStr = path.c_str();
10619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int last = (int) path.size();
10719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    do {
10819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        while (last > 0 && pathStr[--last] != PATH_SLASH[0])
10919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            ;
11019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkASSERT(last > 0);
11119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkString shorter(pathStr, last);
11219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (sk_mkdir(shorter.c_str())) {
11319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            break;
11419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
11519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    } while (true);
11619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    do {
11719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        while (last < (int) path.size() && pathStr[++last] != PATH_SLASH[0])
11819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            ;
11919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkString shorter(pathStr, last);
12019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkAssertResult(sk_mkdir(shorter.c_str()));
12119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    } while (last < (int) path.size());
12219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
12319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
12419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic SkString get_out_path(int dirNo, const char* dirName) {
12519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString path;
12619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkASSERT(dirNo);
12719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkASSERT(dirName);
12819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    path.appendf("%s%d%s%s%s", OUT_DIR_PRE, dirNo, DIR_POST, PATH_SLASH, dirName);
12919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    make_recursive_dir(path);
13019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return path;
13119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
132406654be7a930b484159f5bca107d3b11d8a9edemtklein
13319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic SkString get_sum_path(const char* dirName) {
13419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString path;
13519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkASSERT(dirName);
13619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    path.appendf("%s%d%s%s", OUT_DIR_SUM, SUMMARY_RUN, PATH_SLASH, dirName);
13719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkDebugf("%s\n", path.c_str());
13819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    make_recursive_dir(path);
13919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return path;
14019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
14119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
14219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic SkString make_png_name(const char* filename) {
14319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString pngName = SkString(filename);
14419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    pngName.remove(pngName.size() - 3, 3);
14519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    pngName.append("png");
14619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return pngName;
14719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
148a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
14919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark////////////////////////////////////////////////////////
150a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
151a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comenum TestStep {
152a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    kCompareBits,
153a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    kEncodeFiles,
154a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com};
155a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
156a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comenum {
157dac1d17027dcaa5596885a9f333979418b35001ccaryclark    kMaxLength = 256,
158a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    kMaxFiles = 128,
159a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    kSmallLimit = 1000,
160a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com};
161a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
162a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comstruct TestResult {
163a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    void init(int dirNo) {
164a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        fDirNo = dirNo;
165a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        sk_bzero(fFilename, sizeof(fFilename));
166a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        fTestStep = kCompareBits;
1674431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        fScale = 1;
168a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
169406654be7a930b484159f5bca107d3b11d8a9edemtklein
17019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    void init(int dirNo, const SkString& filename) {
17119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        fDirNo = dirNo;
17219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        strcpy(fFilename, filename.c_str());
17319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        fTestStep = kCompareBits;
174406654be7a930b484159f5bca107d3b11d8a9edemtklein        fScale = 1;
17519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
176a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
177a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkString status() {
178a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkString outStr;
179a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        outStr.printf("%s %d %d\n", fFilename, fPixelError, fTime);
180a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        return outStr;
181a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
182a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
1834431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkString progress() {
1844431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        SkString outStr;
1854431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        outStr.printf("dir=%d %s ", fDirNo, fFilename);
1864431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        if (fPixelError) {
1874431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            outStr.appendf(" err=%d", fPixelError);
1884431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
1894431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        if (fTime) {
1904431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            outStr.appendf(" time=%d", fTime);
1914431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
1924431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        if (fScale != 1) {
1934431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            outStr.appendf(" scale=%d", fScale);
1944431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
1954431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        outStr.appendf("\n");
1964431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return outStr;
1974431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
1984431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
1994431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org
200a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    void test(int dirNo, const SkString& filename) {
201a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        init(dirNo);
202a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        strcpy(fFilename, filename.c_str());
203a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        testOne();
204a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
205a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
206a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    void testOne();
207406654be7a930b484159f5bca107d3b11d8a9edemtklein
208a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    char fFilename[kMaxLength];
209a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    TestStep fTestStep;
210a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int fDirNo;
211a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int fPixelError;
212a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int fTime;
2134431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int fScale;
214a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com};
215a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
2164431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgclass SortByPixel : public TestResult {
2174431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgpublic:
2184431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool operator<(const SortByPixel& rh) const {
2194431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return fPixelError < rh.fPixelError;
220a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
2214431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org};
222a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
2234431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgclass SortByTime : public TestResult {
2244431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgpublic:
2254431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    bool operator<(const SortByTime& rh) const {
2264431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return fTime < rh.fTime;
227a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
2284431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org};
229a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
230dac1d17027dcaa5596885a9f333979418b35001ccaryclarkclass SortByName : public TestResult {
231dac1d17027dcaa5596885a9f333979418b35001ccaryclarkpublic:
232dac1d17027dcaa5596885a9f333979418b35001ccaryclark    bool operator<(const SortByName& rh) const {
233dac1d17027dcaa5596885a9f333979418b35001ccaryclark        return strcmp(fFilename, rh.fFilename) < 0;
234dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
235dac1d17027dcaa5596885a9f333979418b35001ccaryclark};
236dac1d17027dcaa5596885a9f333979418b35001ccaryclark
2374431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.orgstruct TestState {
23819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    void init(int dirNo) {
2394431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        fResult.init(dirNo);
240a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
241a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
2424431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkTDArray<SortByPixel> fPixelWorst;
2434431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    SkTDArray<SortByTime> fSlowest;
244a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    TestResult fResult;
245a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com};
246a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
247a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comstruct TestRunner {
248a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    ~TestRunner();
249a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    void render();
250a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkTDArray<class TestRunnable*> fRunnables;
251a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com};
252a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
253a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comclass TestRunnable : public SkRunnable {
254a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.compublic:
255a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    virtual void run() SK_OVERRIDE {
256a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024);
257a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        (*fTestFun)(&fState);
258a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
259a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
260a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    TestState fState;
261a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    void (*fTestFun)(TestState*);
262a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com};
263a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
264dac1d17027dcaa5596885a9f333979418b35001ccaryclark
265dac1d17027dcaa5596885a9f333979418b35001ccaryclarkclass TestRunnableDir : public TestRunnable {
266dac1d17027dcaa5596885a9f333979418b35001ccaryclarkpublic:
267dac1d17027dcaa5596885a9f333979418b35001ccaryclark    TestRunnableDir(void (*testFun)(TestState*), int dirNo, TestRunner* runner) {
26819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        fState.init(dirNo);
269dac1d17027dcaa5596885a9f333979418b35001ccaryclark        fTestFun = testFun;
270dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
271dac1d17027dcaa5596885a9f333979418b35001ccaryclark
272dac1d17027dcaa5596885a9f333979418b35001ccaryclark};
273dac1d17027dcaa5596885a9f333979418b35001ccaryclark
274dac1d17027dcaa5596885a9f333979418b35001ccaryclarkclass TestRunnableFile : public TestRunnable {
275dac1d17027dcaa5596885a9f333979418b35001ccaryclarkpublic:
276dac1d17027dcaa5596885a9f333979418b35001ccaryclark    TestRunnableFile(void (*testFun)(TestState*), int dirNo, const char* name, TestRunner* runner) {
27719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        fState.init(dirNo);
278dac1d17027dcaa5596885a9f333979418b35001ccaryclark        strcpy(fState.fResult.fFilename, name);
279dac1d17027dcaa5596885a9f333979418b35001ccaryclark        fTestFun = testFun;
280dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
281dac1d17027dcaa5596885a9f333979418b35001ccaryclark};
282dac1d17027dcaa5596885a9f333979418b35001ccaryclark
283dac1d17027dcaa5596885a9f333979418b35001ccaryclarkclass TestRunnableEncode : public TestRunnableFile {
284dac1d17027dcaa5596885a9f333979418b35001ccaryclarkpublic:
285dac1d17027dcaa5596885a9f333979418b35001ccaryclark    TestRunnableEncode(void (*testFun)(TestState*), int dirNo, const char* name, TestRunner* runner)
286dac1d17027dcaa5596885a9f333979418b35001ccaryclark        : TestRunnableFile(testFun, dirNo, name, runner) {
287dac1d17027dcaa5596885a9f333979418b35001ccaryclark        fState.fResult.fTestStep = kEncodeFiles;
288dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
289dac1d17027dcaa5596885a9f333979418b35001ccaryclark};
290dac1d17027dcaa5596885a9f333979418b35001ccaryclark
291a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comTestRunner::~TestRunner() {
292a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    for (int index = 0; index < fRunnables.count(); index++) {
293a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkDELETE(fRunnables[index]);
294a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
295a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
296a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
297a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comvoid TestRunner::render() {
298406654be7a930b484159f5bca107d3b11d8a9edemtklein    SkTaskGroup tg;
299a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    for (int index = 0; index < fRunnables.count(); ++ index) {
300406654be7a930b484159f5bca107d3b11d8a9edemtklein        tg.add(fRunnables[index]);
301a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
302a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
303a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
304a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com////////////////////////////////////////////////
305a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
3062b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com
307a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comstatic int similarBits(const SkBitmap& gr, const SkBitmap& sk) {
308a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    const int kRowCount = 3;
309a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    const int kThreshold = 3;
310a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int width = SkTMin(gr.width(), sk.width());
311a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    if (width < kRowCount) {
312a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        return true;
3137eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com    }
314a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int height = SkTMin(gr.height(), sk.height());
315a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    if (height < kRowCount) {
316a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        return true;
31707e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
318a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int errorTotal = 0;
319a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkTArray<int, true> errorRows;
320a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    errorRows.push_back_n(width * kRowCount);
321a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkAutoLockPixels autoGr(gr);
322a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkAutoLockPixels autoSk(sk);
323a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    for (int y = 0; y < height; ++y) {
324a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkPMColor* grRow = gr.getAddr32(0, y);
325a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkPMColor* skRow = sk.getAddr32(0, y);
326a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        int* base = &errorRows[0];
327a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        int* cOut = &errorRows[y % kRowCount];
328a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        for (int x = 0; x < width; ++x) {
329a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            SkPMColor grColor = grRow[x];
330a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            SkPMColor skColor = skRow[x];
331a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            int dr = SkGetPackedR32(grColor) - SkGetPackedR32(skColor);
332a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            int dg = SkGetPackedG32(grColor) - SkGetPackedG32(skColor);
333a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            int db = SkGetPackedB32(grColor) - SkGetPackedB32(skColor);
334a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            int error = cOut[x] = SkTMax(SkAbs32(dr), SkTMax(SkAbs32(dg), SkAbs32(db)));
335a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            if (error < kThreshold || x < 2) {
336a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                continue;
337a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
338a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            if (base[x - 2] < kThreshold
339a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    || base[width + x - 2] < kThreshold
340a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    || base[width * 2 + x - 2] < kThreshold
341a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    || base[x - 1] < kThreshold
342a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    || base[width + x - 1] < kThreshold
343a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    || base[width * 2 + x - 1] < kThreshold
344a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    || base[x] < kThreshold
345a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    || base[width + x] < kThreshold
346a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    || base[width * 2 + x] < kThreshold) {
347a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                continue;
348a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
349a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            errorTotal += error;
350a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
35107e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
352a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    return errorTotal;
353a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
354a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
355a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comstatic bool addError(TestState* data, const TestResult& testResult) {
3564431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (testResult.fPixelError <= 0 && testResult.fTime <= 0) {
3574431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return false;
3584431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
3594431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int worstCount = data->fPixelWorst.count();
360a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int pixelError = testResult.fPixelError;
3614431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (pixelError > 0) {
3624431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        for (int index = 0; index < worstCount; ++index) {
3634431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            if (pixelError > data->fPixelWorst[index].fPixelError) {
3644431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org                data->fPixelWorst[index] = *(SortByPixel*) &testResult;
3654431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org                return true;
366a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
367a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
3684431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
3694431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int slowCount = data->fSlowest.count();
3704431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    int time = testResult.fTime;
3714431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (time > 0) {
3724431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        for (int index = 0; index < slowCount; ++index) {
3734431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            if (time > data->fSlowest[index].fTime) {
3744431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org                data->fSlowest[index] = *(SortByTime*) &testResult;
3754431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org                return true;
376a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
377a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
37807e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
3794431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (pixelError > 0 && worstCount < kMaxFiles) {
3804431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        *data->fPixelWorst.append() = *(SortByPixel*) &testResult;
3814431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return true;
3824431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
3834431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (time > 0 && slowCount < kMaxFiles) {
3844431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        *data->fSlowest.append() = *(SortByTime*) &testResult;
3854431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return true;
3864431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
3874431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    return false;
388a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
389a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
390a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comstatic SkMSec timePict(SkPicture* pic, SkCanvas* canvas) {
391a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    canvas->save();
392a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkScalar pWidth = pic->cullRect().width();
393a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkScalar pHeight = pic->cullRect().height();
394a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    const SkScalar maxDimension = 1000.0f;
395a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    const int slices = 3;
396a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkScalar xInterval = SkTMax(pWidth - maxDimension, 0.0f) / (slices - 1);
397a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkScalar yInterval = SkTMax(pHeight - maxDimension, 0.0f) / (slices - 1);
398a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips    SkRect rect = {0, 0, SkTMin(maxDimension, pWidth), SkTMin(maxDimension, pHeight) };
399a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    canvas->clipRect(rect);
400a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkMSec start = SkTime::GetMSecs();
401a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    for (int x = 0; x < slices; ++x) {
402a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        for (int y = 0; y < slices; ++y) {
403c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips            pic->playback(canvas);
404a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips            canvas->translate(0, yInterval);
405a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
406a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips        canvas->translate(xInterval, -yInterval * slices);
40707e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
408a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkMSec end = SkTime::GetMSecs();
409a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    canvas->restore();
410a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    return end - start;
411a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
412a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
413a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comstatic void drawPict(SkPicture* pic, SkCanvas* canvas, int scale) {
414a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    canvas->clear(SK_ColorWHITE);
415a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    if (scale != 1) {
416a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        canvas->save();
417a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        canvas->scale(1.0f / scale, 1.0f / scale);
41807e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
419c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips    pic->playback(canvas);
420a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    if (scale != 1) {
421a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        canvas->restore();
422a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
423a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
424a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
425a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comstatic void writePict(const SkBitmap& bitmap, const char* outDir, const char* pngName) {
42619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString outFile = get_sum_path(outDir);
42719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    outFile.appendf("%s%s", PATH_SLASH, pngName);
42819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!SkImageEncoder::EncodeFile(outFile.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100)) {
429a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkDebugf("unable to encode gr %s (width=%d height=%d)\n", pngName,
430a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    bitmap.width(), bitmap.height());
43107e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
432a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
433a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
434a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comvoid TestResult::testOne() {
435a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkPicture* pic = NULL;
436a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    {
437a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    #if DEBUG_SHOW_TEST_NAME
438a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        if (fTestStep == kCompareBits) {
439a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            SkString testName(fFilename);
440a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            const char http[] = "http";
441a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            if (testName.startsWith(http)) {
442a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                testName.remove(0, sizeof(http) - 1);
443a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
444a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            while (testName.startsWith("_")) {
445a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                testName.remove(0, 1);
446a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
447a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            const char dotSkp[] = ".skp";
448a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            if (testName.endsWith(dotSkp)) {
449a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                size_t len = testName.size();
450a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                testName.remove(len - (sizeof(dotSkp) - 1), sizeof(dotSkp) - 1);
451a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
452a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            testName.prepend("skp");
453a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            testName.append("1");
454a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            strncpy(DEBUG_FILENAME_STRING, testName.c_str(), DEBUG_FILENAME_STRING_LENGTH);
455a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        } else if (fTestStep == kEncodeFiles) {
456a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            strncpy(DEBUG_FILENAME_STRING, "", DEBUG_FILENAME_STRING_LENGTH);
457a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
458a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    #endif
45919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkString path = get_in_path(fDirNo, fFilename);
460a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkFILEStream stream(path.c_str());
461a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        if (!stream.isValid()) {
462a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            SkDebugf("invalid stream %s\n", path.c_str());
463a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            goto finish;
464a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
4654431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        pic = SkPicture::CreateFromStream(&stream, &SkImageDecoder::DecodeMemory);
466a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        if (!pic) {
467a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            SkDebugf("unable to decode %s\n", fFilename);
468a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            goto finish;
469a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
470a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips        SkScalar width = pic->cullRect().width();
471a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips        SkScalar height = pic->cullRect().height();
472a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkBitmap oldBitmap, opBitmap;
4734431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        fScale = 1;
4748cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org        while (width / fScale > 32767 || height / fScale > 32767) {
4758cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org            ++fScale;
4768cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org        }
477a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        do {
478a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips            int dimX = SkScalarCeilToInt(width / fScale);
479a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips            int dimY = SkScalarCeilToInt(height / fScale);
480848250415eddc54075f7eb8795e8db79e749c6abreed            if (oldBitmap.tryAllocN32Pixels(dimX, dimY) && opBitmap.tryAllocN32Pixels(dimX, dimY)) {
481a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                break;
482a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
4834431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            SkDebugf("-%d-", fScale);
4848cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org        } while (++fScale < 256);
4854431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        if (fScale >= 256) {
486a8d7f0b13cd4c6d773fcf055fe17db75d260fa05robertphillips            SkDebugf("unable to allocate bitmap for %s (w=%f h=%f)\n", fFilename,
487a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                    width, height);
4884431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            goto finish;
489a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
490a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        oldBitmap.eraseColor(SK_ColorWHITE);
491a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkCanvas oldCanvas(oldBitmap);
492a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        oldCanvas.setAllowSimplifyClip(false);
493a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        opBitmap.eraseColor(SK_ColorWHITE);
494a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkCanvas opCanvas(opBitmap);
495a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        opCanvas.setAllowSimplifyClip(true);
4964431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        drawPict(pic, &oldCanvas, fScale);
4974431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        drawPict(pic, &opCanvas, fScale);
498a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        if (fTestStep == kCompareBits) {
499a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            fPixelError = similarBits(oldBitmap, opBitmap);
500a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            int oldTime = timePict(pic, &oldCanvas);
501a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            int opTime = timePict(pic, &opCanvas);
5024431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            fTime = SkTMax(0, oldTime - opTime);
503a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        } else if (fTestStep == kEncodeFiles) {
504a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            SkString pngStr = make_png_name(fFilename);
505a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            const char* pngName = pngStr.c_str();
506a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            writePict(oldBitmap, outOldDir, pngName);
507a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            writePict(opBitmap, outOpDir, pngName);
5087eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com        }
50907e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
510a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comfinish:
5114431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (pic) {
5124431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        pic->unref();
5134431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
51407e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com}
51507e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com
51619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEFINE_string2(match, m, "PathOpsSkpClipThreaded",
51719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        "[~][^]substring[$] [...] of test name to run.\n"
51819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        "Multiple matches may be separated by spaces.\n"
51919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        "~ causes a matching test to always be skipped\n"
52019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        "^ requires the start of the test to match\n"
52119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        "$ requires the end of the test to match\n"
52219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        "^ and $ requires an exact match\n"
52319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        "If a test does not match any list entry,\n"
52419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        "it is skipped unless some list entry starts with ~");
52519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEFINE_string2(dir, d, NULL, "range of directories (e.g., 1-100)");
52619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEFINE_string2(skp, s, NULL, "skp to test");
52719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEFINE_bool2(single, z, false, "run tests on a single thread internally.");
52819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEFINE_int32(testIndex, 0, "override local test index (PathOpsSkpClipOneOff only).");
52919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEFINE_bool2(verbose, v, false, "enable verbose output.");
53019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
53119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic bool verbose() {
53219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return FLAGS_verbose;
53319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
53419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
53519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkclass Dirs {
536a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.compublic:
53719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    Dirs() {
53819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        reset();
53919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        sk_bzero(fRun, sizeof(fRun));
54019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        fSet = false;
54119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
54219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
54319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int first() const {
54419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        int index = 0;
54519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        while (++index < kMaxDir) {
54619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            if (fRun[index]) {
54719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                return index;
54819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            }
549a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
55019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkASSERT(0);
55119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return -1;
55219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
55319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
55419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int last() const {
55519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        int index = kMaxDir;
55619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        while (--index > 0 && !fRun[index])
557a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            ;
55819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return index;
559a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
560a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
56119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int next() {
56219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        while (++fIndex < kMaxDir) {
56319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            if (fRun[fIndex]) {
56419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                return fIndex;
565a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
566a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
56719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return -1;
568a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
5697eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com
57019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    void reset() {
57119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        fIndex = -1;
57219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
57319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
57419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    void set(int start, int end) {
57519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        while (start < end) {
57619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            fRun[start++] = 1;
57719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
57819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        fSet = true;
57919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
58019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
58119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    void setDefault() {
58219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (!fSet) {
58319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            set(1, 100);
584a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        }
585a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
58607e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com
587a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comprivate:
58819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    enum {
58919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark         kMaxDir = 101
59019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    };
59119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    char fRun[kMaxDir];
592a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int fIndex;
59319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    bool fSet;
59419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark} gDirs;
59519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
59619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkclass Filenames {
59719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkpublic:
59819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    Filenames()
59919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        : fIndex(-1) {
60019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
60119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
60219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const char* next() {
60319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        while (fNames && ++fIndex < fNames->count()) {
60419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            return (*fNames)[fIndex];
60519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
60619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return NULL;
60719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
608406654be7a930b484159f5bca107d3b11d8a9edemtklein
60919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    void set(const SkCommandLineFlags::StringArray& names) {
61019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        fNames = &names;
61119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
61219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
61319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkprivate:
61419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int fIndex;
61519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const SkCommandLineFlags::StringArray* fNames;
61619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark} gNames;
61719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
618406654be7a930b484159f5bca107d3b11d8a9edemtkleinstatic bool buildTestDir(int dirNo, int firstDirNo,
61919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkTDArray<TestResult>* tests, SkTDArray<SortByName*>* sorted) {
62019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString dirName = get_out_path(dirNo, outStatusDir);
62119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!dirName.size()) {
62219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return false;
62319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
62419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkOSFile::Iter iter(dirName.c_str(), "skp");
62519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString filename;
62619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    while (iter.next(&filename)) {
62719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        TestResult test;
62819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        test.init(dirNo);
62919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkString spaceFile(filename);
63019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        char* spaces = spaceFile.writable_str();
63119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        int spaceSize = (int) spaceFile.size();
63219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        for (int index = 0; index < spaceSize; ++index) {
63319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            if (spaces[index] == '.') {
63419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                spaces[index] = ' ';
63519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            }
63619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
63719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        int success = sscanf(spaces, "%s %d %d skp", test.fFilename,
63819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                &test.fPixelError, &test.fTime);
63919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (success < 3) {
64019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            SkDebugf("failed to scan %s matched=%d\n", filename.c_str(), success);
64119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            return false;
64219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
64319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        *tests[dirNo - firstDirNo].append() = test;
64419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
64519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!sorted) {
64619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return true;
64719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
64819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkTDArray<TestResult>& testSet = tests[dirNo - firstDirNo];
64919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int count = testSet.count();
65019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    for (int index = 0; index < count; ++index) {
65119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        *sorted[dirNo - firstDirNo].append() = (SortByName*) &testSet[index];
65219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
65319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (sorted[dirNo - firstDirNo].count()) {
65419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkTQSort<SortByName>(sorted[dirNo - firstDirNo].begin(),
65519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                sorted[dirNo - firstDirNo].end() - 1);
65619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (verbose()) {
65719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            SkDebugf("+");
65819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
65919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
66019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return true;
66119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
66219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
66319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic void testSkpClip(TestState* data) {
66419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    data->fResult.testOne();
66519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString statName(data->fResult.fFilename);
66619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkASSERT(statName.endsWith(".skp"));
66719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    statName.remove(statName.size() - 4, 4);
66819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    statName.appendf(".%d.%d.skp", data->fResult.fPixelError, data->fResult.fTime);
66919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString statusFile = get_out_path(data->fResult.fDirNo, outStatusDir);
67019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!statusFile.size()) {
67119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkDebugf("failed to create %s", statusFile.c_str());
67219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return;
67319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
67419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    statusFile.appendf("%s%s", PATH_SLASH, statName.c_str());
67519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkFILE* file = sk_fopen(statusFile.c_str(), kWrite_SkFILE_Flag);
67619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!file) {
67719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            SkDebugf("failed to create %s", statusFile.c_str());
67819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            return;
67919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
68019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    sk_fclose(file);
68119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (verbose()) {
68219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (data->fResult.fPixelError || data->fResult.fTime) {
68319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            SkDebugf("%s", data->fResult.progress().c_str());
68419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        } else {
68519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            SkDebugf(".");
68619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
68719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
68819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
68919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
69019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkbool Less(const SortByName& a, const SortByName& b);
69119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkbool Less(const SortByName& a, const SortByName& b) {
69219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return a < b;
69319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
694a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
6958cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.orgstatic bool doOneDir(TestState* state, bool threaded) {
696a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    int dirNo = state->fResult.fDirNo;
69719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString dirName = get_in_path(dirNo, NULL);
6984431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    if (!dirName.size()) {
6994431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        return false;
7004431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org    }
70119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkTDArray<TestResult> tests[1];
70219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkTDArray<SortByName*> sorted[1];
70319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!buildTestDir(dirNo, dirNo, tests, sorted)) {
70419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return false;
70519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
706a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkOSFile::Iter iter(dirName.c_str(), "skp");
7072b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com    SkString filename;
7082b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com    while (iter.next(&filename)) {
70919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        for (size_t index = 0; index < skipOverCount; ++index) {
71019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            if (skipOver[index].directory == dirNo
71119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                    && strcmp(filename.c_str(), skipOver[index].filename) == 0) {
7124431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org                goto checkEarlyExit;
7137eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com            }
7147eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com        }
715a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        {
71619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            SortByName name;
71719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            name.init(dirNo);
71819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            strncpy(name.fFilename, filename.c_str(), filename.size() - 4);  // drop .skp
71919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            int count = sorted[0].count();
72019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            int idx = SkTSearch<SortByName, Less>(sorted[0].begin(), count, &name, sizeof(&name));
72119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            if (idx >= 0) {
72219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                SortByName* found = sorted[0][idx];
72319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                (void) addError(state, *found);
72419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                continue;
725a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            }
72619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            TestResult test;
72719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            test.init(dirNo, filename);
72819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            state->fResult = test;
72919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            testSkpClip(state);
73019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#if 0 // artificially limit to a few while debugging code
73119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            static int debugLimit = 0;
73219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            if (++debugLimit == 5) {
73319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                return true;
73407e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com            }
73519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#endif
7362b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com        }
737a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comcheckEarlyExit:
73819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        ;
73907e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    }
740a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    return true;
741a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
742a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
74319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic void initTest() {
744a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#if !defined SK_BUILD_FOR_WIN && !defined SK_BUILD_FOR_MAC
745a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true);
746a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SK_CONF_SET("images.png.suppressDecoderWarnings", true);
747a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com#endif
74807e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com}
74907e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com
750dac1d17027dcaa5596885a9f333979418b35001ccaryclarkstatic void testSkpClipEncode(TestState* data) {
751dac1d17027dcaa5596885a9f333979418b35001ccaryclark    data->fResult.testOne();
75219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (verbose()) {
75319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkDebugf("+");
754dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
755dac1d17027dcaa5596885a9f333979418b35001ccaryclark}
756dac1d17027dcaa5596885a9f333979418b35001ccaryclark
75719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic void encodeFound(TestState& state) {
75819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (verbose()) {
759dac1d17027dcaa5596885a9f333979418b35001ccaryclark        if (state.fPixelWorst.count()) {
760dac1d17027dcaa5596885a9f333979418b35001ccaryclark            SkTDArray<SortByPixel*> worst;
761dac1d17027dcaa5596885a9f333979418b35001ccaryclark            for (int index = 0; index < state.fPixelWorst.count(); ++index) {
762dac1d17027dcaa5596885a9f333979418b35001ccaryclark                *worst.append() = &state.fPixelWorst[index];
763dac1d17027dcaa5596885a9f333979418b35001ccaryclark            }
764dac1d17027dcaa5596885a9f333979418b35001ccaryclark            SkTQSort<SortByPixel>(worst.begin(), worst.end() - 1);
765dac1d17027dcaa5596885a9f333979418b35001ccaryclark            for (int index = 0; index < state.fPixelWorst.count(); ++index) {
766dac1d17027dcaa5596885a9f333979418b35001ccaryclark                const TestResult& result = *worst[index];
767dac1d17027dcaa5596885a9f333979418b35001ccaryclark                SkDebugf("%d %s pixelError=%d\n", result.fDirNo, result.fFilename, result.fPixelError);
768dac1d17027dcaa5596885a9f333979418b35001ccaryclark            }
7694431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
770dac1d17027dcaa5596885a9f333979418b35001ccaryclark        if (state.fSlowest.count()) {
771dac1d17027dcaa5596885a9f333979418b35001ccaryclark            SkTDArray<SortByTime*> slowest;
772dac1d17027dcaa5596885a9f333979418b35001ccaryclark            for (int index = 0; index < state.fSlowest.count(); ++index) {
773dac1d17027dcaa5596885a9f333979418b35001ccaryclark                *slowest.append() = &state.fSlowest[index];
774dac1d17027dcaa5596885a9f333979418b35001ccaryclark            }
775dac1d17027dcaa5596885a9f333979418b35001ccaryclark            if (slowest.count() > 0) {
776dac1d17027dcaa5596885a9f333979418b35001ccaryclark                SkTQSort<SortByTime>(slowest.begin(), slowest.end() - 1);
777dac1d17027dcaa5596885a9f333979418b35001ccaryclark                for (int index = 0; index < slowest.count(); ++index) {
778dac1d17027dcaa5596885a9f333979418b35001ccaryclark                    const TestResult& result = *slowest[index];
779dac1d17027dcaa5596885a9f333979418b35001ccaryclark                    SkDebugf("%d %s time=%d\n", result.fDirNo, result.fFilename, result.fTime);
780dac1d17027dcaa5596885a9f333979418b35001ccaryclark                }
781dac1d17027dcaa5596885a9f333979418b35001ccaryclark            }
7824431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        }
783dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
784406654be7a930b484159f5bca107d3b11d8a9edemtklein    TestRunner testRunner;
785dac1d17027dcaa5596885a9f333979418b35001ccaryclark    for (int index = 0; index < state.fPixelWorst.count(); ++index) {
786dac1d17027dcaa5596885a9f333979418b35001ccaryclark        const TestResult& result = state.fPixelWorst[index];
787dac1d17027dcaa5596885a9f333979418b35001ccaryclark        SkString filename(result.fFilename);
788dac1d17027dcaa5596885a9f333979418b35001ccaryclark        if (!filename.endsWith(".skp")) {
789dac1d17027dcaa5596885a9f333979418b35001ccaryclark            filename.append(".skp");
790cffbcc3b9665f2c928544b6fc6b8a0e22a4210fbcaryclark@google.com        }
791dac1d17027dcaa5596885a9f333979418b35001ccaryclark        *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableEncode,
792dac1d17027dcaa5596885a9f333979418b35001ccaryclark                (&testSkpClipEncode, result.fDirNo, filename.c_str(), &testRunner));
793a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
794dac1d17027dcaa5596885a9f333979418b35001ccaryclark    testRunner.render();
795a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com}
796a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com
79719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkclass Test {
79819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkpublic:
79919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    Test() {}
80019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    virtual ~Test() {}
80119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
80219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const char* getName() { onGetName(&fName); return fName.c_str(); }
80319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    void run() { onRun(); }
80419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
80519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkprotected:
80619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    virtual void onGetName(SkString*) = 0;
80719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    virtual void onRun() = 0;
80819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
80919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkprivate:
81019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString    fName;
81119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark};
81219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
81319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarktypedef SkTRegistry<Test*(*)(void*)> TestRegistry;
81419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
81519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#define DEF_TEST(name)                                        \
81619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    static void test_##name();                       \
81719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    class name##Class : public Test {                                   \
81819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    public:                                                             \
81919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        static Test* Factory(void*) { return SkNEW(name##Class); }      \
82019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    protected:                                                          \
82119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        virtual void onGetName(SkString* name) SK_OVERRIDE {            \
82219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            name->set(#name);                                           \
82319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }                                                               \
82419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        virtual void onRun() SK_OVERRIDE { test_##name(); } \
82519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    };                                                                  \
82619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    static TestRegistry gReg_##name##Class(name##Class::Factory);       \
82719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    static void test_##name()
82819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
82919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEF_TEST(PathOpsSkpClip) {
83019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    gDirs.setDefault();
83119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    initTest();
832a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    SkTArray<TestResult, true> errors;
833a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    TestState state;
83419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    state.init(0);
83519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int dirNo;
83619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    gDirs.reset();
83719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    while ((dirNo = gDirs.next()) > 0) {
83819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (verbose()) {
839a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            SkDebugf("dirNo=%d\n", dirNo);
8407eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com        }
841a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        state.fResult.fDirNo = dirNo;
8428cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org        if (!doOneDir(&state, false)) {
843a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com            break;
8447eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com        }
8457eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com    }
84619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    encodeFound(state);
8477eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com}
8487eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com
849a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.comstatic void testSkpClipMain(TestState* data) {
8508cb1daaa1e4343eb60a7c4f21c12e33de30dad64commit-bot@chromium.org        (void) doOneDir(data, true);
85107e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com}
85207e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com
85319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEF_TEST(PathOpsSkpClipThreaded) {
85419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    gDirs.setDefault();
85519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    initTest();
856406654be7a930b484159f5bca107d3b11d8a9edemtklein    TestRunner testRunner;
85719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int dirNo;
85819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    gDirs.reset();
85919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    while ((dirNo = gDirs.next()) > 0) {
860dac1d17027dcaa5596885a9f333979418b35001ccaryclark        *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableDir,
861a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com                (&testSkpClipMain, dirNo, &testRunner));
8622b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com    }
86307e97fccd2d85076cd22ef411b0773ab92a18abecaryclark@google.com    testRunner.render();
864a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    TestState state;
86519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    state.init(0);
86619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    gDirs.reset();
86719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    while ((dirNo = gDirs.next()) > 0) {
868a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        TestState& testState = testRunner.fRunnables[dirNo - 1]->fState;
869dac1d17027dcaa5596885a9f333979418b35001ccaryclark        SkASSERT(testState.fResult.fDirNo == dirNo);
8704431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org        for (int inner = 0; inner < testState.fPixelWorst.count(); ++inner) {
8714431e7757cfcb8cfa99535eed0e9f156dabf95c2commit-bot@chromium.org            addError(&state, testState.fPixelWorst[inner]);
8727eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com        }
873dac1d17027dcaa5596885a9f333979418b35001ccaryclark        for (int inner = 0; inner < testState.fSlowest.count(); ++inner) {
874dac1d17027dcaa5596885a9f333979418b35001ccaryclark            addError(&state, testState.fSlowest[inner]);
875dac1d17027dcaa5596885a9f333979418b35001ccaryclark        }
876dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
87719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    encodeFound(state);
878dac1d17027dcaa5596885a9f333979418b35001ccaryclark}
879406654be7a930b484159f5bca107d3b11d8a9edemtklein
88019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkstatic bool buildTests(SkTDArray<TestResult>* tests, SkTDArray<SortByName*>* sorted) {
88119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int firstDirNo = gDirs.first();
88219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int dirNo;
88319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    while ((dirNo = gDirs.next()) > 0) {
88419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (!buildTestDir(dirNo, firstDirNo, tests, sorted)) {
885dac1d17027dcaa5596885a9f333979418b35001ccaryclark            return false;
886dac1d17027dcaa5596885a9f333979418b35001ccaryclark        }
887dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
888dac1d17027dcaa5596885a9f333979418b35001ccaryclark    return true;
889dac1d17027dcaa5596885a9f333979418b35001ccaryclark}
890dac1d17027dcaa5596885a9f333979418b35001ccaryclark
89119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEF_TEST(PathOpsSkpClipUberThreaded) {
89219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    gDirs.setDefault();
89319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const int firstDirNo = gDirs.next();
89419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const int lastDirNo = gDirs.last();
89519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    initTest();
89619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int dirCount = lastDirNo - firstDirNo + 1;
89719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkAutoTDeleteArray<SkTDArray<TestResult> > tests(new SkTDArray<TestResult>[dirCount]);
89819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkAutoTDeleteArray<SkTDArray<SortByName*> > sorted(new SkTDArray<SortByName*>[dirCount]);
89919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!buildTests(tests.get(), sorted.get())) {
900dac1d17027dcaa5596885a9f333979418b35001ccaryclark        return;
901dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
902406654be7a930b484159f5bca107d3b11d8a9edemtklein    TestRunner testRunner;
90319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int dirNo;
90419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    gDirs.reset();
90519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    while ((dirNo = gDirs.next()) > 0) {
90619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkString dirName = get_in_path(dirNo, NULL);
907dac1d17027dcaa5596885a9f333979418b35001ccaryclark        if (!dirName.size()) {
908dac1d17027dcaa5596885a9f333979418b35001ccaryclark            continue;
909dac1d17027dcaa5596885a9f333979418b35001ccaryclark        }
910dac1d17027dcaa5596885a9f333979418b35001ccaryclark        SkOSFile::Iter iter(dirName.c_str(), "skp");
911dac1d17027dcaa5596885a9f333979418b35001ccaryclark        SkString filename;
912dac1d17027dcaa5596885a9f333979418b35001ccaryclark        while (iter.next(&filename)) {
91319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            for (size_t index = 0; index < skipOverCount; ++index) {
91419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                if (skipOver[index].directory == dirNo
91519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                        && strcmp(filename.c_str(), skipOver[index].filename) == 0) {
916dac1d17027dcaa5596885a9f333979418b35001ccaryclark                    goto checkEarlyExit;
917dac1d17027dcaa5596885a9f333979418b35001ccaryclark                }
918dac1d17027dcaa5596885a9f333979418b35001ccaryclark            }
91919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            {
92019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                SortByName name;
92119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                name.init(dirNo);
92219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                strncpy(name.fFilename, filename.c_str(), filename.size() - 4);  // drop .skp
92319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                int count = sorted.get()[dirNo - firstDirNo].count();
92419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                if (SkTSearch<SortByName, Less>(sorted.get()[dirNo - firstDirNo].begin(),
92519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                        count, &name, sizeof(&name)) < 0) {
92619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                    *testRunner.fRunnables.append() = SkNEW_ARGS(TestRunnableFile,
92719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                            (&testSkpClip, dirNo, filename.c_str(), &testRunner));
92819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                }
929dac1d17027dcaa5596885a9f333979418b35001ccaryclark            }
930dac1d17027dcaa5596885a9f333979418b35001ccaryclark    checkEarlyExit:
931dac1d17027dcaa5596885a9f333979418b35001ccaryclark            ;
932dac1d17027dcaa5596885a9f333979418b35001ccaryclark        }
933dac1d17027dcaa5596885a9f333979418b35001ccaryclark
934dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
935dac1d17027dcaa5596885a9f333979418b35001ccaryclark    testRunner.render();
93619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkAutoTDeleteArray<SkTDArray<TestResult> > results(new SkTDArray<TestResult>[dirCount]);
93719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!buildTests(results.get(), NULL)) {
938dac1d17027dcaa5596885a9f333979418b35001ccaryclark        return;
939dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
940dac1d17027dcaa5596885a9f333979418b35001ccaryclark    SkTDArray<TestResult> allResults;
941dac1d17027dcaa5596885a9f333979418b35001ccaryclark    for (int dirNo = firstDirNo; dirNo <= lastDirNo; ++dirNo) {
94219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkTDArray<TestResult>& array = results.get()[dirNo - firstDirNo];
943dac1d17027dcaa5596885a9f333979418b35001ccaryclark        allResults.append(array.count(), array.begin());
944dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
945dac1d17027dcaa5596885a9f333979418b35001ccaryclark    int allCount = allResults.count();
946dac1d17027dcaa5596885a9f333979418b35001ccaryclark    SkTDArray<SortByPixel*> pixels;
947dac1d17027dcaa5596885a9f333979418b35001ccaryclark    SkTDArray<SortByTime*> times;
948dac1d17027dcaa5596885a9f333979418b35001ccaryclark    for (int index = 0; index < allCount; ++index) {
949dac1d17027dcaa5596885a9f333979418b35001ccaryclark        *pixels.append() = (SortByPixel*) &allResults[index];
950dac1d17027dcaa5596885a9f333979418b35001ccaryclark        *times.append() = (SortByTime*) &allResults[index];
951dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
952dac1d17027dcaa5596885a9f333979418b35001ccaryclark    TestState state;
953dac1d17027dcaa5596885a9f333979418b35001ccaryclark    if (pixels.count()) {
954dac1d17027dcaa5596885a9f333979418b35001ccaryclark        SkTQSort<SortByPixel>(pixels.begin(), pixels.end() - 1);
955dac1d17027dcaa5596885a9f333979418b35001ccaryclark        for (int inner = 0; inner < kMaxFiles; ++inner) {
956dac1d17027dcaa5596885a9f333979418b35001ccaryclark            *state.fPixelWorst.append() = *pixels[allCount - inner - 1];
957dac1d17027dcaa5596885a9f333979418b35001ccaryclark        }
958dac1d17027dcaa5596885a9f333979418b35001ccaryclark    }
959dac1d17027dcaa5596885a9f333979418b35001ccaryclark    if (times.count()) {
960dac1d17027dcaa5596885a9f333979418b35001ccaryclark        SkTQSort<SortByTime>(times.begin(), times.end() - 1);
961dac1d17027dcaa5596885a9f333979418b35001ccaryclark        for (int inner = 0; inner < kMaxFiles; ++inner) {
962dac1d17027dcaa5596885a9f333979418b35001ccaryclark            *state.fSlowest.append() = *times[allCount - inner - 1];
963dac1d17027dcaa5596885a9f333979418b35001ccaryclark        }
9647eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com    }
96519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    encodeFound(state);
9667eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com}
9677eaa53d8f7e48fd17d02b5e3bd91f90e9c1899efcaryclark@google.com
96819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEF_TEST(PathOpsSkpClipOneOff) {
96919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const int testIndex = FLAGS_testIndex;
97019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    int dirNo = gDirs.next();
97119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (dirNo < 0) {
97219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        dirNo = skipOver[testIndex].directory;
97319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
97419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const char* skp = gNames.next();
97519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!skp) {
97619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        skp = skipOver[testIndex].filename;
977a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
97819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    initTest();
97919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkAssertResult(get_in_path(dirNo, skp).size());
98019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString filename(skp);
981a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    TestResult state;
982a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    state.test(dirNo, filename);
98319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (verbose()) {
984a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com        SkDebugf("%s", state.status().c_str());
985a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    }
986a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    state.fTestStep = kEncodeFiles;
987a2bbc6e19d5332e81784e582c290cc060f40c4c7caryclark@google.com    state.testOne();
9882b34fe01d7b5736b212eb4886afc723a7b9241aeskia.committer@gmail.com}
98919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
99019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEF_TEST(PathOpsTestSkipped) {
99119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    for (size_t index = 0; index < skipOverCount; ++index) {
99219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        const SkipOverTest& skip = skipOver[index];
99319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (!skip.blamePathOps) {
99419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            continue;
99519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
99619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        int dirNo = skip.directory;
99719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        const char* skp = skip.filename;
99819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        initTest();
99919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkAssertResult(get_in_path(dirNo, skp).size());
100019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkString filename(skp);
100119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        TestResult state;
100219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        state.test(dirNo, filename);
100319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (verbose()) {
100419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            SkDebugf("%s", state.status().c_str());
100519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
100619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        state.fTestStep = kEncodeFiles;
100719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        state.testOne();
100819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
100919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
101019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
101119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkDEF_TEST(PathOpsCopyFails) {
101219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    FLAGS_verbose = true;
101319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    for (size_t index = 0; index < skipOverCount; ++index) {
101419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        int dirNo = skipOver[index].directory;
101519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkDebugf("mkdir -p " IN_DIR_PRE "%d" DIR_POST "\n", dirNo);
101619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
101719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    for (size_t index = 0; index < skipOverCount; ++index) {
101819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        int dirNo = skipOver[index].directory;
101919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        const char* filename = skipOver[index].filename;
102019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkDebugf("rsync -av cary-linux.cnc:/tera" PATH_SLASH "skps" PATH_SLASH "slave"
102119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            "%d" DIR_POST "/%s " IN_DIR_PRE "%d" DIR_POST "\n", dirNo, filename, dirNo);
102219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
102319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
102419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
102519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarktemplate TestRegistry* TestRegistry::gHead;
102619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
102719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkclass Iter {
102819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkpublic:
102919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    Iter() { this->reset(); }
103019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    void reset() { fReg = TestRegistry::Head(); }
103119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
103219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    Test* next() {
103319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (fReg) {
103419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            TestRegistry::Factory fact = fReg->factory();
103519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            fReg = fReg->next();
103619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            Test* test = fact(NULL);
103719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            return test;
103819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
103919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        return NULL;
104019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
104119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
104219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkprivate:
104319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    const TestRegistry* fReg;
104419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark};
104519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
104619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkint tool_main(int argc, char** argv);
104719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkint tool_main(int argc, char** argv) {
104819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SetupCrashHandler();
104919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkCommandLineFlags::SetUsage("");
105019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkCommandLineFlags::Parse(argc, argv);
105119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkGraphics::Init();
105219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkString header("PathOps SkpClip:");
105319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!FLAGS_match.isEmpty()) {
105419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        header.appendf(" --match");
105519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        for (int index = 0; index < FLAGS_match.count(); ++index) {
105619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            header.appendf(" %s", FLAGS_match[index]);
105719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
105819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
105919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!FLAGS_dir.isEmpty()) {
106019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        int count = FLAGS_dir.count();
106119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        for (int i = 0; i < count; ++i) {
106219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            const char* range = FLAGS_dir[i];
106319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            const char* dash = strchr(range, '-');
106419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            if (!dash) {
106519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                dash = strchr(range, ',');
106619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            }
106719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            int first = atoi(range);
106819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            int last = dash ? atoi(dash + 1) : first;
106919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            if (!first || !last) {
107019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                SkDebugf("couldn't parse --dir %s\n", range);
107119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark                return 1;
107219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            }
107319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            gDirs.set(first, last);
107419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
107519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
107619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (!FLAGS_skp.isEmpty()) {
107719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        gNames.set(FLAGS_skp);
107819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
107919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#ifdef SK_DEBUG
108019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    header.append(" SK_DEBUG");
108119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#else
108219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    header.append(" SK_RELEASE");
108319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#endif
108419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    header.appendf(" skia_arch_width=%d", (int)sizeof(void*) * 8);
108519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    if (FLAGS_verbose) {
108619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        header.appendf("\n");
108719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
108819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkDebugf(header.c_str());
108919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    Iter iter;
109019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    Test* test;
109119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    while ((test = iter.next()) != NULL) {
109219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        SkAutoTDelete<Test> owned(test);
109319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        if (!SkCommandLineFlags::ShouldSkip(FLAGS_match, test->getName())) {
109419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark            test->run();
109519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark        }
109619eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    }
109719eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    SkGraphics::Term();
109819eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return 0;
109919eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
110019eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark
110119eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
110219eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclarkint main(int argc, char * const argv[]) {
110319eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark    return tool_main(argc, (char**) argv);
110419eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark}
110519eb3b2f0aa6dce5c0335230a8930e90733e5d5dcaryclark#endif
1106