/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * Code for the "gm" (Golden Master) rendering comparison tool.
 *
 * If you make changes to this, re-run the self-tests at gm/tests/run.sh
 * to make sure they still pass... you may need to change the expected
 * results of the self-test.
 */

#include "gm.h"
#include "gm_error.h"
#include "gm_expectations.h"
#include "system_preferences.h"
#include "SkBitmap.h"
#include "SkColorPriv.h"
#include "SkCommandLineFlags.h"
#include "SkData.h"
#include "SkDeferredCanvas.h"
#include "SkDevice.h"
#include "SkDocument.h"
#include "SkDrawFilter.h"
#include "SkForceLinking.h"
#include "SkGPipe.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
#include "SkImageEncoder.h"
#include "SkJSONCPP.h"
#include "SkOSFile.h"
#include "SkPDFRasterizer.h"
#include "SkPicture.h"
#include "SkPictureRecorder.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkSurface.h"
#include "SkTArray.h"
#include "SkTDict.h"
#include "SamplePipeControllers.h"

#ifdef SK_DEBUG
static const bool kDebugOnly = true;
#define GR_DUMP_FONT_CACHE 0
#else
static const bool kDebugOnly = false;
#endif

__SK_FORCE_IMAGE_DECODER_LINKING;

#if SK_SUPPORT_GPU
#include "GrContextFactory.h"
#include "SkGpuDevice.h"
typedef GrContextFactory::GLContextType GLContextType;
#define DEFAULT_CACHE_VALUE -1
static int gGpuCacheSizeBytes;
static int gGpuCacheSizeCount;
#else
class GrContextFactory;
class GrContext;
class GrSurface;
typedef int GLContextType;
#endif

#define DEBUGFAIL_SEE_STDERR SkDEBUGFAIL("see stderr for message")

DECLARE_bool(useDocumentInsteadOfDevice);

#ifdef SK_SUPPORT_PDF
    #include "SkPDFDevice.h"
    #include "SkPDFDocument.h"
#endif

// Until we resolve http://code.google.com/p/skia/issues/detail?id=455 ,
// stop writing out XPS-format image baselines in gm.
#undef SK_SUPPORT_XPS
#ifdef SK_SUPPORT_XPS
    #include "SkXPSDevice.h"
#endif

#ifdef SK_BUILD_FOR_MAC
    #include "SkCGUtils.h"
#endif

using namespace skiagm;

class Iter {
public:
    Iter() {
        this->reset();
    }

    void reset() {
        fReg = GMRegistry::Head();
    }

    GM* next() {
        if (fReg) {
            GMRegistry::Factory fact = fReg->factory();
            fReg = fReg->next();
            return fact(0);
        }
        return NULL;
    }

    static int Count() {
        const GMRegistry* reg = GMRegistry::Head();
        int count = 0;
        while (reg) {
            count += 1;
            reg = reg->next();
        }
        return count;
    }

private:
    const GMRegistry* fReg;
};

// TODO(epoger): Right now, various places in this code assume that all the
// image files read/written by GM use this file extension.
// Search for references to this constant to find these assumptions.
const static char kPNG_FileExtension[] = "png";

enum Backend {
    kRaster_Backend,
    kGPU_Backend,
    kPDF_Backend,
    kXPS_Backend,
};

enum BbhType {
    kNone_BbhType,
    kRTree_BbhType,
    kTileGrid_BbhType,
    kQuadTree_BbhType
};

enum ConfigFlags {
    kNone_ConfigFlag  = 0x0,
    /* Write GM images if a write path is provided. */
    kWrite_ConfigFlag = 0x1,
    /* Read reference GM images if a read path is provided. */
    kRead_ConfigFlag  = 0x2,
    kRW_ConfigFlag    = (kWrite_ConfigFlag | kRead_ConfigFlag),
};

struct ConfigData {
    SkBitmap::Config                fConfig;
    Backend                         fBackend;
    GLContextType                   fGLContextType; // GPU backend only
    int                             fSampleCnt;     // GPU backend only
    ConfigFlags                     fFlags;
    const char*                     fName;
    bool                            fRunByDefault;
};

struct PDFRasterizerData {
    bool        (*fRasterizerFunction)(SkStream*, SkBitmap*);
    const char* fName;
    bool        fRunByDefault;
};

class BWTextDrawFilter : public SkDrawFilter {
public:
    virtual bool filter(SkPaint*, Type) SK_OVERRIDE;
};
bool BWTextDrawFilter::filter(SkPaint* p, Type t) {
    if (kText_Type == t) {
        p->setAntiAlias(false);
    }
    return true;
}

struct PipeFlagComboData {
    const char* name;
    uint32_t flags;
};

static PipeFlagComboData gPipeWritingFlagCombos[] = {
    { "", 0 },
    { " cross-process", SkGPipeWriter::kCrossProcess_Flag },
    { " cross-process, shared address", SkGPipeWriter::kCrossProcess_Flag
        | SkGPipeWriter::kSharedAddressSpace_Flag }
};

static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap);
DECLARE_int32(pdfRasterDpi);

const static ErrorCombination kDefaultIgnorableErrorTypes = ErrorCombination()
    .plus(kMissingExpectations_ErrorType)
    .plus(kIntentionallySkipped_ErrorType);

class GMMain {
public:
    GMMain() : fUseFileHierarchy(false), fWriteChecksumBasedFilenames(false),
               fIgnorableErrorTypes(kDefaultIgnorableErrorTypes),
               fMismatchPath(NULL), fMissingExpectationsPath(NULL), fTestsRun(0),
               fRenderModesEncountered(1) {}

    /**
     * Assemble shortNamePlusConfig from (surprise!) shortName and configName.
     *
     * The method for doing so depends on whether we are using hierarchical naming.
     * For example, shortName "selftest1" and configName "8888" could be assembled into
     * either "selftest1_8888" or "8888/selftest1".
     */
    SkString make_shortname_plus_config(const char *shortName, const char *configName) {
        SkString name;
        if (0 == strlen(configName)) {
            name.append(shortName);
        } else if (fUseFileHierarchy) {
            name.appendf("%s%c%s", configName, SkPATH_SEPARATOR, shortName);
        } else {
            name.appendf("%s_%s", shortName, configName);
        }
        return name;
    }

    /**
     * Assemble filename, suitable for writing out the results of a particular test.
     */
    SkString make_filename(const char *path,
                           const char *shortName,
                           const char *configName,
                           const char *renderModeDescriptor,
                           const char *suffix) {
        SkString filename = make_shortname_plus_config(shortName, configName);
        filename.append(renderModeDescriptor);
        filename.appendUnichar('.');
        filename.append(suffix);
        return SkOSPath::SkPathJoin(path, filename.c_str());
    }

    /**
     * Assemble filename suitable for writing out an SkBitmap.
     */
    SkString make_bitmap_filename(const char *path,
                                  const char *shortName,
                                  const char *configName,
                                  const char *renderModeDescriptor,
                                  const GmResultDigest &bitmapDigest) {
        if (fWriteChecksumBasedFilenames) {
            SkString filename;
            filename.append(bitmapDigest.getHashType());
            filename.appendUnichar('_');
            filename.append(shortName);
            filename.appendUnichar('_');
            filename.append(bitmapDigest.getDigestValue());
            filename.appendUnichar('.');
            filename.append(kPNG_FileExtension);
            return SkOSPath::SkPathJoin(path, filename.c_str());
        } else {
            return make_filename(path, shortName, configName, renderModeDescriptor,
                                 kPNG_FileExtension);
        }
    }

    /* since PNG insists on unpremultiplying our alpha, we take no
       precision chances and force all pixels to be 100% opaque,
       otherwise on compare we may not get a perfect match.
    */
    static void force_all_opaque(const SkBitmap& bitmap) {
        SkColorType colorType = bitmap.colorType();
        switch (colorType) {
        case kN32_SkColorType:
            force_all_opaque_8888(bitmap);
            break;
        case kRGB_565_SkColorType:
            // nothing to do here; 565 bitmaps are inherently opaque
            break;
        default:
            SkDebugf("unsupported bitmap colorType %d\n", colorType);
            DEBUGFAIL_SEE_STDERR;
        }
    }

    static void force_all_opaque_8888(const SkBitmap& bitmap) {
        SkAutoLockPixels lock(bitmap);
        for (int y = 0; y < bitmap.height(); y++) {
            for (int x = 0; x < bitmap.width(); x++) {
                *bitmap.getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT);
            }
        }
    }

    static ErrorCombination write_bitmap(const SkString& path, const SkBitmap& bitmap) {
        // TODO(epoger): Now that we have removed force_all_opaque()
        // from this method, we should be able to get rid of the
        // transformation to 8888 format also.
        SkBitmap copy;
        bitmap.copyTo(&copy, kN32_SkColorType);
        if (!SkImageEncoder::EncodeFile(path.c_str(), copy,
                                        SkImageEncoder::kPNG_Type,
                                        100)) {
            SkDebugf("FAILED to write bitmap: %s\n", path.c_str());
            return ErrorCombination(kWritingReferenceImage_ErrorType);
        }
        return kEmpty_ErrorCombination;
    }

    /**
     * Add all render modes encountered thus far to the "modes" array.
     */
    void GetRenderModesEncountered(SkTArray<SkString> &modes) {
        SkTDict<int>::Iter iter(this->fRenderModesEncountered);
        const char* mode;
        while ((mode = iter.next(NULL)) != NULL) {
            SkString modeAsString = SkString(mode);
            // TODO(epoger): It seems a bit silly that all of these modes were
            // recorded with a leading "-" which we have to remove here
            // (except for mode "", which means plain old original mode).
            // But that's how renderModeDescriptor has been passed into
            // compare_test_results_to_reference_bitmap() historically,
            // and changing that now may affect other parts of our code.
            if (modeAsString.startsWith("-")) {
                modeAsString.remove(0, 1);
            }
            modes.push_back(modeAsString);
        }
    }

    /**
     * Returns true if failures on this test should be ignored.
     */
    bool ShouldIgnoreTest(const char *name) const {
        for (int i = 0; i < fIgnorableTestNames.count(); i++) {
            if (fIgnorableTestNames[i].equals(name)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Calls RecordTestResults to record that we skipped a test.
     *
     * Depending on the backend, this may mean that we skipped a single rendermode, or all
     * rendermodes; see http://skbug.com/1994 and https://codereview.chromium.org/129203002/
     */
    void RecordSkippedTest(const SkString& shortNamePlusConfig,
                           const char renderModeDescriptor [], Backend backend) {
        if (kRaster_Backend == backend) {
            // Skipping a test on kRaster_Backend means that we will skip ALL renderModes
            // (as opposed to other backends, on which we only run the default renderMode).
            //
            // We cannot call RecordTestResults yet, because we won't know the full set of
            // renderModes until we have run all tests.
            fTestsSkippedOnAllRenderModes.push_back(shortNamePlusConfig);
        } else {
            this->RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                    renderModeDescriptor);
        }
    }

    /**
     * Records the results of this test in fTestsRun and fFailedTests.
     *
     * We even record successes, and errors that we regard as
     * "ignorable"; we can filter them out later.
     */
    void RecordTestResults(const ErrorCombination& errorCombination,
                           const SkString& shortNamePlusConfig,
                           const char renderModeDescriptor []) {
        // Things to do regardless of errorCombination.
        fTestsRun++;
        int renderModeCount = 0;
        this->fRenderModesEncountered.find(renderModeDescriptor, &renderModeCount);
        renderModeCount++;
        this->fRenderModesEncountered.set(renderModeDescriptor, renderModeCount);

        if (errorCombination.isEmpty()) {
            return;
        }

        // Things to do only if there is some error condition.
        SkString fullName = shortNamePlusConfig;
        fullName.append(renderModeDescriptor);
        for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) {
            ErrorType type = static_cast<ErrorType>(typeInt);
            if (errorCombination.includes(type)) {
                fFailedTests[type].push_back(fullName);
            }
        }
    }

    /**
     * Return the number of significant (non-ignorable) errors we have
     * encountered so far.
     */
    int NumSignificantErrors() {
        int significantErrors = 0;
        for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) {
            ErrorType type = static_cast<ErrorType>(typeInt);
            if (!fIgnorableErrorTypes.includes(type)) {
                significantErrors += fFailedTests[type].count();
            }
        }
        return significantErrors;
    }

    /**
     * Display the summary of results with this ErrorType.
     *
     * @param type which ErrorType
     * @param verbose whether to be all verbose about it
     */
    void DisplayResultTypeSummary(ErrorType type, bool verbose) {
        bool isIgnorableType = fIgnorableErrorTypes.includes(type);

        SkString line;
        if (isIgnorableType) {
            line.append("[ ] ");
        } else {
            line.append("[*] ");
        }

        SkTArray<SkString> *failedTestsOfThisType = &fFailedTests[type];
        int count = failedTestsOfThisType->count();
        line.appendf("%d %s", count, getErrorTypeName(type));
        if (!isIgnorableType || verbose) {
            line.append(":");
            for (int i = 0; i < count; ++i) {
                line.append(" ");
                line.append((*failedTestsOfThisType)[i]);
            }
        }
        SkDebugf("%s\n", line.c_str());
    }

    /**
     * List contents of fFailedTests to stdout.
     *
     * @param verbose whether to be all verbose about it
     */
    void ListErrors(bool verbose) {
        // First, print a single summary line.
        SkString summary;
        summary.appendf("Ran %d tests:", fTestsRun);
        for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) {
            ErrorType type = static_cast<ErrorType>(typeInt);
            summary.appendf(" %s=%d", getErrorTypeName(type), fFailedTests[type].count());
        }
        SkDebugf("%s\n", summary.c_str());

        // Now, for each failure type, list the tests that failed that way.
        for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) {
            this->DisplayResultTypeSummary(static_cast<ErrorType>(typeInt), verbose);
        }
        SkDebugf("(results marked with [*] will cause nonzero return value)\n");
    }

    static ErrorCombination write_document(const SkString& path, SkStreamAsset* asset) {
        SkFILEWStream stream(path.c_str());
        if (!stream.writeStream(asset, asset->getLength())) {
            SkDebugf("FAILED to write document: %s\n", path.c_str());
            return ErrorCombination(kWritingReferenceImage_ErrorType);
        }
        return kEmpty_ErrorCombination;
    }

    /**
     * Prepare an SkBitmap to render a GM into.
     *
     * After you've rendered the GM into the SkBitmap, you must call
     * complete_bitmap()!
     *
     * @todo thudson 22 April 2011 - could refactor this to take in
     * a factory to generate the context, always call readPixels()
     * (logically a noop for rasters, if wasted time), and thus collapse the
     * GPU special case and also let this be used for SkPicture testing.
     */
    static void setup_bitmap(const ConfigData& gRec, SkISize& size,
                             SkBitmap* bitmap) {
        bitmap->allocConfigPixels(gRec.fConfig, size.width(), size.height());
        bitmap->eraseColor(SK_ColorTRANSPARENT);
    }

    /**
     * Any finalization steps we need to perform on the SkBitmap after
     * we have rendered the GM into it.
     *
     * It's too bad that we are throwing away alpha channel data
     * we could otherwise be examining, but this had always been happening
     * before... it was buried within the compare() method at
     * https://code.google.com/p/skia/source/browse/trunk/gm/gmmain.cpp?r=7289#305 .
     *
     * Apparently we need this, at least for bitmaps that are either:
     * (a) destined to be written out as PNG files, or
     * (b) compared against bitmaps read in from PNG files
     * for the reasons described just above the force_all_opaque() method.
     *
     * Neglecting to do this led to the difficult-to-diagnose
     * http://code.google.com/p/skia/issues/detail?id=1079 ('gm generating
     * spurious pixel_error messages as of r7258')
     *
     * TODO(epoger): Come up with a better solution that allows us to
     * compare full pixel data, including alpha channel, while still being
     * robust in the face of transformations to/from PNG files.
     * Options include:
     *
     * 1. Continue to call force_all_opaque(), but ONLY for bitmaps that
     *    will be written to, or compared against, PNG files.
     *    PRO: Preserve/compare alpha channel info for the non-PNG cases
     *         (comparing different renderModes in-memory)
     *    CON: The bitmaps (and hash digests) for these non-PNG cases would be
     *         different than those for the PNG-compared cases, and in the
     *         case of a failed renderMode comparison, how would we write the
     *         image to disk for examination?
     *
     * 2. Always compute image hash digests from PNG format (either
     *    directly from the the bytes of a PNG file, or capturing the
     *    bytes we would have written to disk if we were writing the
     *    bitmap out as a PNG).
     *    PRO: I think this would allow us to never force opaque, and to
     *         the extent that alpha channel data can be preserved in a PNG
     *         file, we could observe it.
     *    CON: If we read a bitmap from disk, we need to take its hash digest
     *         from the source PNG (we can't compute it from the bitmap we
     *         read out of the PNG, because we will have already premultiplied
     *         the alpha).
     *    CON: Seems wasteful to convert a bitmap to PNG format just to take
     *         its hash digest. (Although we're wasting lots of effort already
     *         calling force_all_opaque().)
     *
     * 3. Make the alpha premultiply/unpremultiply routines 100% consistent,
     *    so we can transform images back and forth without fear of off-by-one
     *    errors.
     *    CON: Math is hard.
     *
     * 4. Perform a "close enough" comparison of bitmaps (+/- 1 bit in each
     *    channel), rather than demanding absolute equality.
     *    CON: Can't do this with hash digests.
     */
    static void complete_bitmap(SkBitmap* bitmap) {
        force_all_opaque(*bitmap);
    }

    static void installFilter(SkCanvas* canvas);

    static void invokeGM(GM* gm, SkCanvas* canvas, bool isPDF, bool isDeferred) {
        SkAutoCanvasRestore acr(canvas, true);

        if (!isPDF) {
            canvas->concat(gm->getInitialTransform());
        }
        installFilter(canvas);
        gm->setCanvasIsDeferred(isDeferred);
        gm->draw(canvas);
        canvas->setDrawFilter(NULL);
    }

    static ErrorCombination generate_image(GM* gm, const ConfigData& gRec,
                                           GrSurface* gpuTarget,
                                           SkBitmap* bitmap,
                                           bool deferred) {
        SkISize size (gm->getISize());
        setup_bitmap(gRec, size, bitmap);
        const SkImageInfo info = bitmap->info();

        SkAutoTUnref<SkSurface> surface;
        SkAutoTUnref<SkCanvas> canvas;

        if (gRec.fBackend == kRaster_Backend) {
            surface.reset(SkSurface::NewRasterDirect(info,
                                                     bitmap->getPixels(),
                                                     bitmap->rowBytes()));
            if (deferred) {
                canvas.reset(SkDeferredCanvas::Create(surface));
            } else {
                canvas.reset(SkRef(surface->getCanvas()));
            }
            invokeGM(gm, canvas, false, deferred);
            canvas->flush();
        }
#if SK_SUPPORT_GPU
        else {  // GPU
            surface.reset(SkSurface::NewRenderTargetDirect(gpuTarget->asRenderTarget()));
            if (deferred) {
                canvas.reset(SkDeferredCanvas::Create(surface));
            } else {
                canvas.reset(SkRef(surface->getCanvas()));
            }
            invokeGM(gm, canvas, false, deferred);
            // the device is as large as the current rendertarget, so
            // we explicitly only readback the amount we expect (in
            // size) overwrite our previous allocation
            bitmap->setConfig(SkImageInfo::MakeN32Premul(size.fWidth, size.fHeight));
            canvas->readPixels(bitmap, 0, 0);
        }
#endif
        complete_bitmap(bitmap);
        return kEmpty_ErrorCombination;
    }

    static void generate_image_from_picture(GM* gm, const ConfigData& gRec,
                                            SkPicture* pict, SkBitmap* bitmap,
                                            SkScalar scale = SK_Scalar1,
                                            bool tile = false) {
        SkISize size = gm->getISize();
        setup_bitmap(gRec, size, bitmap);

        if (tile) {
            // Generate the result image by rendering to tiles and accumulating
            // the results in 'bitmap'

            // This 16x16 tiling matches the settings applied to 'pict' in
            // 'generate_new_picture'
            SkISize tileSize = SkISize::Make(16, 16);

            SkBitmap tileBM;
            setup_bitmap(gRec, tileSize, &tileBM);
            SkCanvas tileCanvas(tileBM);
            installFilter(&tileCanvas);

            SkCanvas bmpCanvas(*bitmap);
            SkPaint bmpPaint;
            bmpPaint.setXfermodeMode(SkXfermode::kSrc_Mode);

            for (int yTile = 0; yTile < (size.height()+15)/16; ++yTile) {
                for (int xTile = 0; xTile < (size.width()+15)/16; ++xTile) {
                    int saveCount = tileCanvas.save();
                    SkMatrix mat(tileCanvas.getTotalMatrix());
                    mat.postTranslate(SkIntToScalar(-xTile*tileSize.width()),
                                      SkIntToScalar(-yTile*tileSize.height()));
                    tileCanvas.setMatrix(mat);
                    pict->draw(&tileCanvas);
                    tileCanvas.flush();
                    tileCanvas.restoreToCount(saveCount);
                    bmpCanvas.drawBitmap(tileBM,
                                         SkIntToScalar(xTile * tileSize.width()),
                                         SkIntToScalar(yTile * tileSize.height()),
                                         &bmpPaint);
                }
            }
        } else {
            SkCanvas canvas(*bitmap);
            installFilter(&canvas);
            canvas.scale(scale, scale);
            canvas.drawPicture(*pict);
            complete_bitmap(bitmap);
        }
    }

    static bool generate_pdf(GM* gm, SkDynamicMemoryWStream& pdf) {
#ifdef SK_SUPPORT_PDF
        SkMatrix initialTransform = gm->getInitialTransform();
        if (FLAGS_useDocumentInsteadOfDevice) {
            SkISize pageISize = gm->getISize();
            SkAutoTUnref<SkDocument> pdfDoc(
                    SkDocument::CreatePDF(&pdf, NULL,
                                          encode_to_dct_data,
                                          SkIntToScalar(FLAGS_pdfRasterDpi)));

            if (!pdfDoc.get()) {
                return false;
            }

            SkCanvas* canvas = NULL;
            canvas = pdfDoc->beginPage(SkIntToScalar(pageISize.width()),
                                       SkIntToScalar(pageISize.height()));
            canvas->concat(initialTransform);

            invokeGM(gm, canvas, true, false);

            return pdfDoc->close();
        } else {
            SkISize pageSize = gm->getISize();
            SkPDFDevice* dev = NULL;
            if (initialTransform.isIdentity()) {
                dev = new SkPDFDevice(pageSize, pageSize, initialTransform);
            } else {
                SkRect content = SkRect::MakeWH(SkIntToScalar(pageSize.width()),
                                                SkIntToScalar(pageSize.height()));
                initialTransform.mapRect(&content);
                content.intersect(0, 0, SkIntToScalar(pageSize.width()),
                                  SkIntToScalar(pageSize.height()));
                SkISize contentSize =
                    SkISize::Make(SkScalarRoundToInt(content.width()),
                                  SkScalarRoundToInt(content.height()));
                dev = new SkPDFDevice(pageSize, contentSize, initialTransform);
            }
            dev->setDCTEncoder(encode_to_dct_data);
            dev->setRasterDpi(SkIntToScalar(FLAGS_pdfRasterDpi));
            SkAutoUnref aur(dev);
            SkCanvas c(dev);
            invokeGM(gm, &c, true, false);
            SkPDFDocument doc;
            doc.appendPage(dev);
            doc.emitPDF(&pdf);
        }
#endif  // SK_SUPPORT_PDF
        return true; // Do not report failure if pdf is not supported.
    }

    static void generate_xps(GM* gm, SkDynamicMemoryWStream& xps) {
#ifdef SK_SUPPORT_XPS
        SkISize size = gm->getISize();

        SkSize trimSize = SkSize::Make(SkIntToScalar(size.width()),
                                       SkIntToScalar(size.height()));
        static const SkScalar inchesPerMeter = SkScalarDiv(10000, 254);
        static const SkScalar upm = 72 * inchesPerMeter;
        SkVector unitsPerMeter = SkPoint::Make(upm, upm);
        static const SkScalar ppm = 200 * inchesPerMeter;
        SkVector pixelsPerMeter = SkPoint::Make(ppm, ppm);

        SkXPSDevice* dev = new SkXPSDevice();
        SkAutoUnref aur(dev);

        SkCanvas c(dev);
        dev->beginPortfolio(&xps);
        dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize);
        invokeGM(gm, &c, false, false);
        dev->endSheet();
        dev->endPortfolio();

#endif
    }

    /**
     * Log more detail about the mistmatch between expectedBitmap and
     * actualBitmap.
     */
    void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& actualBitmap,
                             const char *testName) {
        const int expectedWidth = expectedBitmap.width();
        const int expectedHeight = expectedBitmap.height();
        const int width = actualBitmap.width();
        const int height = actualBitmap.height();
        if ((expectedWidth != width) || (expectedHeight != height)) {
            SkDebugf("---- %s: dimension mismatch -- expected [%d %d], actual [%d %d]\n",
                     testName, expectedWidth, expectedHeight, width, height);
            return;
        }

        if ((kN32_SkColorType != expectedBitmap.colorType()) ||
            (kN32_SkColorType != actualBitmap.colorType())) {
            SkDebugf("---- %s: not computing max per-channel pixel mismatch because non-8888\n",
                     testName);
            return;
        }

        SkAutoLockPixels alp0(expectedBitmap);
        SkAutoLockPixels alp1(actualBitmap);
        int errR = 0;
        int errG = 0;
        int errB = 0;
        int errA = 0;
        int differingPixels = 0;

        for (int y = 0; y < height; ++y) {
            const SkPMColor* expectedPixelPtr = expectedBitmap.getAddr32(0, y);
            const SkPMColor* actualPixelPtr = actualBitmap.getAddr32(0, y);
            for (int x = 0; x < width; ++x) {
                SkPMColor expectedPixel = *expectedPixelPtr++;
                SkPMColor actualPixel = *actualPixelPtr++;
                if (expectedPixel != actualPixel) {
                    differingPixels++;
                    errR = SkMax32(errR, SkAbs32((int)SkGetPackedR32(expectedPixel) -
                                                 (int)SkGetPackedR32(actualPixel)));
                    errG = SkMax32(errG, SkAbs32((int)SkGetPackedG32(expectedPixel) -
                                                 (int)SkGetPackedG32(actualPixel)));
                    errB = SkMax32(errB, SkAbs32((int)SkGetPackedB32(expectedPixel) -
                                                 (int)SkGetPackedB32(actualPixel)));
                    errA = SkMax32(errA, SkAbs32((int)SkGetPackedA32(expectedPixel) -
                                                 (int)SkGetPackedA32(actualPixel)));
                }
            }
        }
        SkDebugf("---- %s: %d (of %d) differing pixels, "
                 "max per-channel mismatch R=%d G=%d B=%d A=%d\n",
                 testName, differingPixels, width*height, errR, errG, errB, errA);
    }

    /**
     * Compares actual hash digest to expectations, returning the set of errors
     * (if any) that we saw along the way.
     *
     * If fMismatchPath has been set, and there are pixel diffs, then the
     * actual bitmap will be written out to a file within fMismatchPath.
     * And similarly for fMissingExpectationsPath...
     *
     * @param expectations what expectations to compare actualBitmap against
     * @param actualBitmapAndDigest the SkBitmap we actually generated, and its GmResultDigest
     * @param shortName name of test, e.g. "selftest1"
     * @param configName name of config, e.g. "8888"
     * @param renderModeDescriptor e.g., "-rtree", "-deferred"
     * @param addToJsonSummary whether to add these results (both actual and
     *        expected) to the JSON summary. Regardless of this setting, if
     *        we find an image mismatch in this test, we will write these
     *        results to the JSON summary.  (This is so that we will always
     *        report errors across rendering modes, such as pipe vs tiled.
     *        See https://codereview.chromium.org/13650002/ )
     */
    ErrorCombination compare_to_expectations(Expectations expectations,
                                             const BitmapAndDigest& actualBitmapAndDigest,
                                             const char *shortName, const char *configName,
                                             const char *renderModeDescriptor,
                                             bool addToJsonSummary) {
        ErrorCombination errors;
        SkString shortNamePlusConfig = make_shortname_plus_config(shortName, configName);
        SkString completeNameString(shortNamePlusConfig);
        completeNameString.append(renderModeDescriptor);
        completeNameString.append(".");
        completeNameString.append(kPNG_FileExtension);
        const char* completeName = completeNameString.c_str();

        if (expectations.empty()) {
            errors.add(kMissingExpectations_ErrorType);

            // Write out the "actuals" for any tests without expectations, if we have
            // been directed to do so.
            if (fMissingExpectationsPath) {
                SkString path = make_bitmap_filename(fMissingExpectationsPath, shortName,
                                                     configName, renderModeDescriptor,
                                                     actualBitmapAndDigest.fDigest);
                write_bitmap(path, actualBitmapAndDigest.fBitmap);
            }

        } else if (!expectations.match(actualBitmapAndDigest.fDigest)) {
            addToJsonSummary = true;
            // The error mode we record depends on whether this was running
            // in a non-standard renderMode.
            if ('\0' == *renderModeDescriptor) {
                errors.add(kExpectationsMismatch_ErrorType);
            } else {
                errors.add(kRenderModeMismatch_ErrorType);
            }

            // Write out the "actuals" for any mismatches, if we have
            // been directed to do so.
            if (fMismatchPath) {
                SkString path = make_bitmap_filename(fMismatchPath, shortName, configName,
                                                     renderModeDescriptor,
                                                     actualBitmapAndDigest.fDigest);
                write_bitmap(path, actualBitmapAndDigest.fBitmap);
            }

            // If we have access to a single expected bitmap, log more
            // detail about the mismatch.
            const SkBitmap *expectedBitmapPtr = expectations.asBitmap();
            if (NULL != expectedBitmapPtr) {
                report_bitmap_diffs(*expectedBitmapPtr, actualBitmapAndDigest.fBitmap,
                                    completeName);
            }
        }

        if (addToJsonSummary) {
            add_actual_results_to_json_summary(completeName, actualBitmapAndDigest.fDigest, errors,
                                               expectations.ignoreFailure());
            add_expected_results_to_json_summary(completeName, expectations);
        }

        return errors;
    }

    /**
     * Add this result to the appropriate JSON collection of actual results (but just ONE),
     * depending on errors encountered.
     */
    void add_actual_results_to_json_summary(const char testName[],
                                            const GmResultDigest &actualResultDigest,
                                            ErrorCombination errors,
                                            bool ignoreFailure) {
#ifdef SK_BUILD_JSON_WRITER
        Json::Value jsonActualResults = actualResultDigest.asJsonTypeValuePair();
        Json::Value *resultCollection = NULL;

        if (errors.isEmpty()) {
            resultCollection = &this->fJsonActualResults_Succeeded;
        } else if (errors.includes(kRenderModeMismatch_ErrorType)) {
            resultCollection = &this->fJsonActualResults_Failed;
        } else if (errors.includes(kExpectationsMismatch_ErrorType)) {
            if (ignoreFailure) {
                resultCollection = &this->fJsonActualResults_FailureIgnored;
            } else {
                resultCollection = &this->fJsonActualResults_Failed;
            }
        } else if (errors.includes(kMissingExpectations_ErrorType)) {
            // TODO: What about the case where there IS an expected
            // image hash digest, but that gm test doesn't actually
            // run?  For now, those cases will always be ignored,
            // because gm only looks at expectations that correspond
            // to gm tests that were actually run.
            //
            // Once we have the ability to express expectations as a
            // JSON file, we should fix this (and add a test case for
            // which an expectation is given but the test is never
            // run).
            resultCollection = &this->fJsonActualResults_NoComparison;
        }

        // If none of the above cases match, we don't add it to ANY tally of actual results.
        if (resultCollection) {
            (*resultCollection)[testName] = jsonActualResults;
        }
#endif
    }

    /**
     * Add this test to the JSON collection of expected results.
     */
    void add_expected_results_to_json_summary(const char testName[],
                                              Expectations expectations) {
#ifdef SK_BUILD_JSON_WRITER
        this->fJsonExpectedResults[testName] = expectations.asJsonValue();
#endif
    }

    /**
     * Compare actualBitmap to expectations stored in this->fExpectationsSource.
     *
     * @param gm which test generated the actualBitmap
     * @param gRec
     * @param configName The config name to look for in the expectation file.
     * @param actualBitmapAndDigest ptr to bitmap generated by this run, or NULL
     *        if we don't have a usable bitmap representation
     */
    ErrorCombination compare_test_results_to_stored_expectations(
        GM* gm, const ConfigData& gRec, const char* configName,
        const BitmapAndDigest* actualBitmapAndDigest) {
        ErrorCombination errors;

        if (NULL == actualBitmapAndDigest) {
            // Note that we intentionally skipped validating the results for
            // this test, because we don't know how to generate an SkBitmap
            // version of the output.
            errors.add(ErrorCombination(kIntentionallySkipped_ErrorType));
        } else if (!(gRec.fFlags & kWrite_ConfigFlag)) {
            // We don't record the results for this test or compare them
            // against any expectations, because the output image isn't
            // meaningful.
            // See https://code.google.com/p/skia/issues/detail?id=1410 ('some
            // GM result images not available for download from Google Storage')
            errors.add(ErrorCombination(kIntentionallySkipped_ErrorType));
        } else {
            ExpectationsSource *expectationsSource = this->fExpectationsSource.get();
            SkString nameWithExtension = make_shortname_plus_config(gm->getName(), configName);
            nameWithExtension.append(".");
            nameWithExtension.append(kPNG_FileExtension);

            if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) {
                /*
                 * Get the expected results for this test, as one or more allowed
                 * hash digests. The current implementation of expectationsSource
                 * get this by computing the hash digest of a single PNG file on disk.
                 *
                 * TODO(epoger): This relies on the fact that
                 * force_all_opaque() was called on the bitmap before it
                 * was written to disk as a PNG in the first place. If
                 * not, the hash digest returned here may not match the
                 * hash digest of actualBitmap, which *has* been run through
                 * force_all_opaque().
                 * See comments above complete_bitmap() for more detail.
                 */
                Expectations expectations = expectationsSource->get(nameWithExtension.c_str());
                if (this->ShouldIgnoreTest(gm->getName())) {
                    expectations.setIgnoreFailure(true);
                }
                errors.add(compare_to_expectations(expectations, *actualBitmapAndDigest,
                                                   gm->getName(), configName, "", true));
            } else {
                // If we are running without expectations, we still want to
                // record the actual results.
                add_actual_results_to_json_summary(nameWithExtension.c_str(),
                                                   actualBitmapAndDigest->fDigest,
                                                   ErrorCombination(kMissingExpectations_ErrorType),
                                                   false);
                errors.add(ErrorCombination(kMissingExpectations_ErrorType));
            }
        }
        return errors;
    }

    /**
     * Compare actualBitmap to referenceBitmap.
     *
     * @param shortName test name, e.g. "selftest1"
     * @param configName configuration name, e.g. "8888"
     * @param renderModeDescriptor
     * @param actualBitmap actual bitmap generated by this run
     * @param referenceBitmap bitmap we expected to be generated
     */
    ErrorCombination compare_test_results_to_reference_bitmap(
        const char *shortName, const char *configName, const char *renderModeDescriptor,
        SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) {

        SkASSERT(referenceBitmap);
        Expectations expectations(*referenceBitmap);
        BitmapAndDigest actualBitmapAndDigest(actualBitmap);

        // TODO: Eliminate RecordTestResults from here.
        // Results recording code for the test_drawing path has been refactored so that
        // RecordTestResults is only called once, at the topmost level. However, the
        // other paths have not yet been refactored, and RecordTestResults has been added
        // here to maintain proper behavior for calls not coming from the test_drawing path.
        ErrorCombination errors;
        errors.add(compare_to_expectations(expectations, actualBitmapAndDigest, shortName,
                                           configName, renderModeDescriptor, false));
        SkString shortNamePlusConfig = make_shortname_plus_config(shortName, configName);
        RecordTestResults(errors, shortNamePlusConfig, renderModeDescriptor);

        return errors;
    }

    static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t recordFlags,
                                           SkScalar scale = SK_Scalar1) {
        int width = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().width()), scale));
        int height = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().height()), scale));

        SkAutoTDelete<SkBBHFactory> factory;
        if (kTileGrid_BbhType == bbhType) {
            SkTileGridFactory::TileGridInfo info;
            info.fMargin.setEmpty();
            info.fOffset.setZero();
            info.fTileInterval.set(16, 16);
            factory.reset(SkNEW_ARGS(SkTileGridFactory, (info)));
        } else if (kQuadTree_BbhType == bbhType) {
            factory.reset(SkNEW(SkQuadTreeFactory));
        } else if (kRTree_BbhType == bbhType) {
            factory.reset(SkNEW(SkRTreeFactory));
        }
        SkPictureRecorder recorder;
        SkCanvas* cv = recorder.beginRecording(width, height, factory.get(), recordFlags);
        cv->scale(scale, scale);
        invokeGM(gm, cv, false, false);
        return recorder.endRecording();
    }

    static SkPicture* stream_to_new_picture(const SkPicture& src) {
        SkDynamicMemoryWStream storage;
        src.serialize(&storage, NULL);
        SkAutoTUnref<SkStreamAsset> pictReadback(storage.detachAsStream());
        SkPicture* retval = SkPicture::CreateFromStream(pictReadback,
                                                        &SkImageDecoder::DecodeMemory);
        return retval;
    }

    // Test: draw into a bitmap or pdf.
    // Depending on flags, possibly compare to an expected image.
    // If writePath is not NULL, also write images (or documents) to the specified path.
    ErrorCombination test_drawing(GM* gm, const ConfigData& gRec,
                                  const SkTDArray<const PDFRasterizerData*> &pdfRasterizers,
                                  const char writePath [],
                                  GrSurface* gpuTarget,
                                  SkBitmap* bitmap) {
        ErrorCombination errors;
        SkDynamicMemoryWStream document;
        SkString path;

        if (gRec.fBackend == kRaster_Backend ||
            gRec.fBackend == kGPU_Backend) {
            // Early exit if we can't generate the image.
            errors.add(generate_image(gm, gRec, gpuTarget, bitmap, false));
            if (!errors.isEmpty()) {
                // TODO: Add a test to exercise what the stdout and
                // JSON look like if we get an "early error" while
                // trying to generate the image.
                return errors;
            }
            BitmapAndDigest bitmapAndDigest(*bitmap);
            errors.add(compare_test_results_to_stored_expectations(
                           gm, gRec, gRec.fName, &bitmapAndDigest));

            if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
                path = make_bitmap_filename(writePath, gm->getName(), gRec.fName,
                                            "", bitmapAndDigest.fDigest);
                errors.add(write_bitmap(path, bitmapAndDigest.fBitmap));
            }
        } else if (gRec.fBackend == kPDF_Backend) {
            if (!generate_pdf(gm, document)) {
                errors.add(kGeneratePdfFailed_ErrorType);
            } else {
                SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream());
                if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
                    path = make_filename(writePath, gm->getName(), gRec.fName, "", "pdf");
                    errors.add(write_document(path, documentStream));
                }

                if (!(gm->getFlags() & GM::kSkipPDFRasterization_Flag)) {
                    for (int i = 0; i < pdfRasterizers.count(); i++) {
                        SkBitmap pdfBitmap;
                        documentStream->rewind();
                        bool success = (*pdfRasterizers[i]->fRasterizerFunction)(
                                documentStream.get(), &pdfBitmap);
                        if (!success) {
                            SkDebugf("FAILED to render PDF for %s using renderer %s\n",
                                     gm->getName(),
                                     pdfRasterizers[i]->fName);
                            continue;
                        }

                        SkString configName(gRec.fName);
                        configName.append("-");
                        configName.append(pdfRasterizers[i]->fName);

                        BitmapAndDigest bitmapAndDigest(pdfBitmap);
                        errors.add(compare_test_results_to_stored_expectations(
                                   gm, gRec, configName.c_str(), &bitmapAndDigest));

                        if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
                            path = make_bitmap_filename(writePath, gm->getName(),
                                                        configName.c_str(),
                                                        "", bitmapAndDigest.fDigest);
                            errors.add(write_bitmap(path, bitmapAndDigest.fBitmap));
                        }
                    }
                } else {
                    errors.add(kIntentionallySkipped_ErrorType);
                }
            }
        } else if (gRec.fBackend == kXPS_Backend) {
            generate_xps(gm, document);
            SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream());

            errors.add(compare_test_results_to_stored_expectations(
                           gm, gRec, gRec.fName, NULL));

            if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
                path = make_filename(writePath, gm->getName(), gRec.fName, "", "xps");
                errors.add(write_document(path, documentStream));
            }
        } else {
            SkASSERT(false);
        }
        return errors;
    }

    ErrorCombination test_deferred_drawing(GM* gm,
                                           const ConfigData& gRec,
                                           const SkBitmap& referenceBitmap,
                                           GrSurface* gpuTarget) {
        if (gRec.fBackend == kRaster_Backend ||
            gRec.fBackend == kGPU_Backend) {
            const char renderModeDescriptor[] = "-deferred";
            SkBitmap bitmap;
            // Early exit if we can't generate the image, but this is
            // expected in some cases, so don't report a test failure.
            ErrorCombination errors = generate_image(gm, gRec, gpuTarget, &bitmap, true);
            // TODO(epoger): This logic is the opposite of what is
            // described above... if we succeeded in generating the
            // -deferred image, we exit early!  We should fix this
            // ASAP, because it is hiding -deferred errors... but for
            // now, I'm leaving the logic as it is so that the
            // refactoring change
            // https://codereview.chromium.org/12992003/ is unblocked.
            //
            // Filed as https://code.google.com/p/skia/issues/detail?id=1180
            // ('image-surface gm test is failing in "deferred" mode,
            // and gm is not reporting the failure')
            if (errors.isEmpty()) {
                // TODO(epoger): Report this as a new ErrorType,
                // something like kImageGeneration_ErrorType?
                return kEmpty_ErrorCombination;
            }
            return compare_test_results_to_reference_bitmap(
                gm->getName(), gRec.fName, renderModeDescriptor, bitmap, &referenceBitmap);
        }
        return kEmpty_ErrorCombination;
    }

    ErrorCombination test_pipe_playback(GM* gm, const ConfigData& gRec,
                                        const SkBitmap& referenceBitmap, bool simulateFailure) {
        const SkString shortNamePlusConfig = make_shortname_plus_config(gm->getName(),
                                                                        gRec.fName);
        ErrorCombination errors;
        for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) {
            SkString renderModeDescriptor("-pipe");
            renderModeDescriptor.append(gPipeWritingFlagCombos[i].name);

            if (gm->getFlags() & GM::kSkipPipe_Flag
                || (gPipeWritingFlagCombos[i].flags == SkGPipeWriter::kCrossProcess_Flag
                    && gm->getFlags() & GM::kSkipPipeCrossProcess_Flag)) {
                RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                  renderModeDescriptor.c_str());
                errors.add(kIntentionallySkipped_ErrorType);
            } else {
                SkBitmap bitmap;
                SkISize size = gm->getISize();
                setup_bitmap(gRec, size, &bitmap);
                SkCanvas canvas(bitmap);
                installFilter(&canvas);
                // Pass a decoding function so the factory GM (which has an SkBitmap
                // with encoded data) will not fail playback.
                PipeController pipeController(&canvas, &SkImageDecoder::DecodeMemory);
                SkGPipeWriter writer;
                SkCanvas* pipeCanvas = writer.startRecording(&pipeController,
                                                             gPipeWritingFlagCombos[i].flags,
                                                             size.width(), size.height());
                if (!simulateFailure) {
                    invokeGM(gm, pipeCanvas, false, false);
                }
                complete_bitmap(&bitmap);
                writer.endRecording();
                errors.add(compare_test_results_to_reference_bitmap(
                    gm->getName(), gRec.fName, renderModeDescriptor.c_str(), bitmap,
                    &referenceBitmap));
                if (!errors.isEmpty()) {
                    break;
                }
            }
        }
        return errors;
    }

    ErrorCombination test_tiled_pipe_playback(GM* gm, const ConfigData& gRec,
                                              const SkBitmap& referenceBitmap) {
        const SkString shortNamePlusConfig = make_shortname_plus_config(gm->getName(),
                                                                        gRec.fName);
        ErrorCombination errors;
        for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) {
            SkString renderModeDescriptor("-tiled pipe");
            renderModeDescriptor.append(gPipeWritingFlagCombos[i].name);

            if ((gm->getFlags() & GM::kSkipPipe_Flag) ||
                (gm->getFlags() & GM::kSkipTiled_Flag)) {
                RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                  renderModeDescriptor.c_str());
                errors.add(kIntentionallySkipped_ErrorType);
            } else {
                SkBitmap bitmap;
                SkISize size = gm->getISize();
                setup_bitmap(gRec, size, &bitmap);
                SkCanvas canvas(bitmap);
                installFilter(&canvas);
                TiledPipeController pipeController(bitmap, &SkImageDecoder::DecodeMemory);
                SkGPipeWriter writer;
                SkCanvas* pipeCanvas = writer.startRecording(&pipeController,
                                                             gPipeWritingFlagCombos[i].flags,
                                                             size.width(), size.height());
                invokeGM(gm, pipeCanvas, false, false);
                complete_bitmap(&bitmap);
                writer.endRecording();
                errors.add(compare_test_results_to_reference_bitmap(gm->getName(), gRec.fName,
                                                                    renderModeDescriptor.c_str(),
                                                                    bitmap, &referenceBitmap));
                if (!errors.isEmpty()) {
                    break;
                }
            }
        }
        return errors;
    }

    //
    // member variables.
    // They are public for now, to allow easier setting by tool_main().
    //

    bool fUseFileHierarchy, fWriteChecksumBasedFilenames;
    ErrorCombination fIgnorableErrorTypes;
    SkTArray<SkString> fIgnorableTestNames;

    const char* fMismatchPath;
    const char* fMissingExpectationsPath;

    // collection of tests that have failed with each ErrorType
    SkTArray<SkString> fFailedTests[kLast_ErrorType+1];
    SkTArray<SkString> fTestsSkippedOnAllRenderModes;
    int fTestsRun;
    SkTDict<int> fRenderModesEncountered;

    // Where to read expectations (expected image hash digests, etc.) from.
    // If unset, we don't do comparisons.
    SkAutoTUnref<ExpectationsSource> fExpectationsSource;

#ifdef SK_BUILD_JSON_WRITER
    // JSON summaries that we generate as we go (just for output).
    Json::Value fJsonExpectedResults;
    Json::Value fJsonActualResults_Failed;
    Json::Value fJsonActualResults_FailureIgnored;
    Json::Value fJsonActualResults_NoComparison;
    Json::Value fJsonActualResults_Succeeded;
#endif
}; // end of GMMain class definition

#if SK_SUPPORT_GPU
static const GLContextType kDontCare_GLContextType = GrContextFactory::kNative_GLContextType;
#else
static const GLContextType kDontCare_GLContextType = 0;
#endif

static const ConfigData gRec[] = {
    { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType,                  0, kRW_ConfigFlag,    "8888",         true },
#if 0   // stop testing this (for now at least) since we want to remove support for it (soon please!!!)
    { SkBitmap::kARGB_4444_Config, kRaster_Backend, kDontCare_GLContextType,                  0, kRW_ConfigFlag,    "4444",         true },
#endif
    { SkBitmap::kRGB_565_Config,   kRaster_Backend, kDontCare_GLContextType,                  0, kRW_ConfigFlag,    "565",          true },
#if SK_SUPPORT_GPU
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kNative_GLContextType,  0, kRW_ConfigFlag,    "gpu",          true },
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kNative_GLContextType, 16, kRW_ConfigFlag,    "msaa16",       false},
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kNative_GLContextType,  4, kRW_ConfigFlag,    "msaa4",        false},
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kNVPR_GLContextType,    4, kRW_ConfigFlag,    "nvprmsaa4",   true },
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kNVPR_GLContextType,   16, kRW_ConfigFlag,    "nvprmsaa16",  false},
    /* The gpudebug context does not generate meaningful images, so don't record
     * the images it generates!  We only run it to look for asserts. */
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kDebug_GLContextType,   0, kNone_ConfigFlag,  "gpudebug",     kDebugOnly},
    /* The gpunull context does the least amount of work possible and doesn't
       generate meaninful images, so don't record them!. It can be run to
       isolate the CPU-side processing expense from the GPU-side.
      */
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kNull_GLContextType,    0, kNone_ConfigFlag,  "gpunull",      kDebugOnly},
#if SK_ANGLE
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kANGLE_GLContextType,   0, kRW_ConfigFlag,    "angle",        true },
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kANGLE_GLContextType,  16, kRW_ConfigFlag,    "anglemsaa16",  true },
#endif // SK_ANGLE
#ifdef SK_MESA
    { SkBitmap::kARGB_8888_Config, kGPU_Backend,    GrContextFactory::kMESA_GLContextType,    0, kRW_ConfigFlag,    "mesa",         true },
#endif // SK_MESA
#endif // SK_SUPPORT_GPU
#ifdef SK_SUPPORT_XPS
    /* At present we have no way of comparing XPS files (either natively or by converting to PNG). */
    { SkBitmap::kARGB_8888_Config, kXPS_Backend,    kDontCare_GLContextType,                  0, kWrite_ConfigFlag, "xps",          true },
#endif // SK_SUPPORT_XPS
#ifdef SK_SUPPORT_PDF
    { SkBitmap::kARGB_8888_Config, kPDF_Backend,    kDontCare_GLContextType,                  0, kRW_ConfigFlag,    "pdf",          true },
#endif // SK_SUPPORT_PDF
};

static bool SkNoRasterizePDF(SkStream*, SkBitmap*) { return false; }

static const PDFRasterizerData kPDFRasterizers[] = {
#ifdef SK_BUILD_FOR_MAC
    { &SkPDFDocumentToBitmap, "mac",     true },
#endif
#ifdef SK_BUILD_POPPLER
    { &SkPopplerRasterizePDF, "poppler", true },
#endif
#ifdef SK_BUILD_NATIVE_PDF_RENDERER
    { &SkNativeRasterizePDF,  "native",  true },
#endif  // SK_BUILD_NATIVE_PDF_RENDERER
    // The following exists so that this array is never zero length.
    { &SkNoRasterizePDF,      "none",    false},
};

static const char kDefaultsConfigStr[] = "defaults";
static const char kExcludeConfigChar = '~';

static SkString configUsage() {
    SkString result;
    result.appendf("Space delimited list of which configs to run. Possible options: [");
    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
        SkASSERT(gRec[i].fName != kDefaultsConfigStr);
        if (i > 0) {
            result.append("|");
        }
        result.appendf("%s", gRec[i].fName);
    }
    result.append("]\n");
    result.appendf("The default value is: \"");
    SkString firstDefault;
    SkString allButFirstDefaults;
    SkString nonDefault;
    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
        if (gRec[i].fRunByDefault) {
            if (i > 0) {
                result.append(" ");
            }
            result.append(gRec[i].fName);
            if (firstDefault.isEmpty()) {
                firstDefault = gRec[i].fName;
            } else {
                if (!allButFirstDefaults.isEmpty()) {
                    allButFirstDefaults.append(" ");
                }
                allButFirstDefaults.append(gRec[i].fName);
            }
        } else {
            nonDefault = gRec[i].fName;
        }
    }
    result.append("\"\n");
    result.appendf("\"%s\" evaluates to the default set of configs.\n", kDefaultsConfigStr);
    result.appendf("Prepending \"%c\" on a config name excludes it from the set of configs to run.\n"
                   "Exclusions always override inclusions regardless of order.\n",
                   kExcludeConfigChar);
    result.appendf("E.g. \"--config %s %c%s %s\" will run these configs:\n\t%s %s",
                   kDefaultsConfigStr,
                   kExcludeConfigChar,
                   firstDefault.c_str(),
                   nonDefault.c_str(),
                   allButFirstDefaults.c_str(),
                   nonDefault.c_str());
    return result;
}

static SkString pdfRasterizerUsage() {
    SkString result;
    result.appendf("Space delimited list of which PDF rasterizers to run. Possible options: [");
    // For this (and further) loops through kPDFRasterizers, there is a typecast to int to avoid
    // the compiler giving an "comparison of unsigned expression < 0 is always false" warning
    // and turning it into a build-breaking error.
    for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) {
        if (i > 0) {
            result.append(" ");
        }
        result.append(kPDFRasterizers[i].fName);
    }
    result.append("]\n");
    result.append("The default value is: \"");
    for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) {
        if (kPDFRasterizers[i].fRunByDefault) {
            if (i > 0) {
                result.append(" ");
            }
            result.append(kPDFRasterizers[i].fName);
        }
    }
    result.append("\"");
    return result;
}

// Macro magic to convert a numeric preprocessor token into a string.
// Adapted from http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string
// This should probably be moved into one of our common headers...
#define TOSTRING_INTERNAL(x) #x
#define TOSTRING(x) TOSTRING_INTERNAL(x)

// Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath").
DEFINE_string(config, "", configUsage().c_str());
DEFINE_string(pdfRasterizers, "default", pdfRasterizerUsage().c_str());
DEFINE_bool(deferred, false, "Exercise the deferred rendering test pass.");
DEFINE_bool(dryRun, false, "Don't actually run the tests, just print what would have been done.");
DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip.");
DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing.");
#if SK_SUPPORT_GPU
DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte size or "
              "object count. " TOSTRING(DEFAULT_CACHE_VALUE) " for either value means "
              "use the default. 0 for either disables the cache.");
#endif
DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure "
            "when reading/writing files.");
DEFINE_string(ignoreErrorTypes, kDefaultIgnorableErrorTypes.asString(" ").c_str(),
              "Space-separated list of ErrorTypes that should be ignored. If any *other* error "
              "types are encountered, the tool will exit with a nonzero return value.");
DEFINE_string(ignoreFailuresFile, "", "Path to file containing a list of tests for which we "
              "should ignore failures.\n"
              "The file should list one test per line, except for comment lines starting with #");
DEFINE_bool2(leaks, l, false, "show leaked ref cnt'd objects.");
DEFINE_string(match, "", "[~][^]substring[$] [...] of test name to run.\n"
              "Multiple matches may be separated by spaces.\n"
              "~ causes a matching test to always be skipped\n"
              "^ requires the start of the test to match\n"
              "$ requires the end of the test to match\n"
              "^ and $ requires an exact match\n"
              "If a test does not match any list entry,\n"
              "it is skipped unless some list entry starts with ~");
DEFINE_string(missingExpectationsPath, "", "Write images for tests without expectations "
              "into this directory.");
DEFINE_string(mismatchPath, "", "Write images for tests that failed due to "
              "pixel mismatches into this directory.");
DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which "
              "testIndex %% divisor == remainder.");
DEFINE_bool(pipe, false, "Exercise the SkGPipe replay test pass.");
DEFINE_bool(quadtree, false, "Exercise the QuadTree variant of SkPicture test pass.");
DEFINE_string2(readPath, r, "", "Read reference images from this dir, and report "
               "any differences between those and the newly generated ones.");
DEFINE_bool(replay, false, "Exercise the SkPicture replay test pass.");
#if SK_SUPPORT_GPU
DEFINE_bool(resetGpuContext, false, "Reset the GrContext prior to running each GM.");
#endif
DEFINE_string2(resourcePath, i, "resources", "Directory that stores image resources.");
DEFINE_bool(rtree, false, "Exercise the R-Tree variant of SkPicture test pass.");
DEFINE_bool(serialize, false, "Exercise the SkPicture serialization & deserialization test pass.");
DEFINE_bool(simulatePipePlaybackFailure, false, "Simulate a rendering failure in pipe mode only.");
DEFINE_bool(tiledPipe, false, "Exercise tiled SkGPipe replay.");
DEFINE_bool(tileGrid, false, "Exercise the tile grid variant of SkPicture.");
DEFINE_string(tileGridReplayScales, "", "Space separated list of floating-point scale "
              "factors to be used for tileGrid playback testing. Default value: 1.0");
DEFINE_bool2(verbose, v, false, "Give more detail (e.g. list all GMs run, more info about "
             "each test).");
DEFINE_bool(writeChecksumBasedFilenames, false, "When writing out actual images, use checksum-"
            "based filenames, as rebaseline.py will use when downloading them from Google Storage");
#ifdef SK_BUILD_JSON_WRITER
DEFINE_string(writeJsonSummaryPath, "", "Write a JSON-formatted result summary to this file.");
#endif
DEFINE_string2(writePath, w, "",  "Write rendered images into this directory.");
DEFINE_string2(writePicturePath, p, "", "Write .skp files into this directory.");
DEFINE_int32(pdfJpegQuality, -1, "Encodes images in JPEG at quality level N, "
             "which can be in range 0-100). N = -1 will disable JPEG compression. "
             "Default is N = 100, maximum quality.");
// TODO(edisonn): pass a matrix instead of forcePerspectiveMatrix
// Either the 9 numbers defining the matrix
// or probably more readable would be to replace it with a set of a few predicates
// Like --prerotate 100 200 10 --posttranslate 10, 10
// Probably define spacial names like centerx, centery, top, bottom, left, right
// then we can write something reabable like --rotate centerx centery 90
DEFINE_bool(forcePerspectiveMatrix, false, "Force a perspective matrix.");
DEFINE_bool(useDocumentInsteadOfDevice, false, "Use SkDocument::CreateFoo instead of SkFooDevice.");
DEFINE_int32(pdfRasterDpi, 72, "Scale at which at which the non suported "
             "features in PDF are rasterized. Must be be in range 0-10000. "
             "Default is 72. N = 0 will disable rasterizing features like "
             "text shadows or perspective bitmaps.");
static SkData* encode_to_dct_data(size_t*, const SkBitmap& bitmap) {
    // Filter output of warnings that JPEG is not available for the image.
    if (bitmap.width() >= 65500 || bitmap.height() >= 65500) return NULL;
    if (FLAGS_pdfJpegQuality == -1) return NULL;

    SkBitmap bm = bitmap;
#if defined(SK_BUILD_FOR_MAC)
    // Workaround bug #1043 where bitmaps with referenced pixels cause
    // CGImageDestinationFinalize to crash
    SkBitmap copy;
    bitmap.deepCopyTo(&copy);
    bm = copy;
#endif

    SkPixelRef* pr = bm.pixelRef();
    if (pr != NULL) {
        SkData* data = pr->refEncodedData();
        if (data != NULL) {
            return data;
        }
    }

    return SkImageEncoder::EncodeData(bm,
                                      SkImageEncoder::kJPEG_Type,
                                      FLAGS_pdfJpegQuality);
}

static int findConfig(const char config[]) {
    for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
        if (!strcmp(config, gRec[i].fName)) {
            return (int) i;
        }
    }
    return -1;
}

static const PDFRasterizerData* findPDFRasterizer(const char rasterizer[]) {
    for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); i++) {
        if (!strcmp(rasterizer, kPDFRasterizers[i].fName)) {
            return &kPDFRasterizers[i];
        }
    }
    return NULL;
}

template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) {
    int index = array->find(value);
    if (index < 0) {
        *array->append() = value;
    }
}

/**
 * Run this test in a number of different drawing modes (pipe,
 * deferred, tiled, etc.), confirming that the resulting bitmaps all
 * *exactly* match comparisonBitmap.
 *
 * Returns all errors encountered while doing so.
 */
ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compareConfig,
                                    const SkBitmap &comparisonBitmap,
                                    const SkTDArray<SkScalar> &tileGridReplayScales);
ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compareConfig,
                                    const SkBitmap &comparisonBitmap,
                                    const SkTDArray<SkScalar> &tileGridReplayScales) {
    ErrorCombination errorsForAllModes;
    uint32_t gmFlags = gm->getFlags();
    const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(gm->getName(),
                                                                           compareConfig.fName);

    SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0);
    SkAutoUnref aur(pict);
    if (FLAGS_replay) {
        const char renderModeDescriptor[] = "-replay";
        if (gmFlags & GM::kSkipPicture_Flag) {
            gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                     renderModeDescriptor);
            errorsForAllModes.add(kIntentionallySkipped_ErrorType);
        } else {
            SkBitmap bitmap;
            gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap);
            errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
                gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
                &comparisonBitmap));
        }
    }

    if (FLAGS_serialize) {
        const char renderModeDescriptor[] = "-serialize";
        if (gmFlags & GM::kSkipPicture_Flag) {
            gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                     renderModeDescriptor);
            errorsForAllModes.add(kIntentionallySkipped_ErrorType);
        } else {
            SkPicture* repict = gmmain.stream_to_new_picture(*pict);
            SkAutoUnref aurr(repict);
            SkBitmap bitmap;
            gmmain.generate_image_from_picture(gm, compareConfig, repict, &bitmap);
            errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
                gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
                &comparisonBitmap));
        }
    }

    if ((1 == FLAGS_writePicturePath.count()) &&
        !(gmFlags & GM::kSkipPicture_Flag)) {
        const char* pictureSuffix = "skp";
        // TODO(epoger): Make sure this still works even though the
        // filename now contains the config name (it used to contain
        // just the shortName).  I think this is actually an
        // *improvement*, because now runs with different configs will
        // write out their SkPictures to separate files rather than
        // overwriting each other.  But we should make sure it doesn't
        // break anybody.
        SkString path = gmmain.make_filename(FLAGS_writePicturePath[0], gm->getName(),
                                             compareConfig.fName, "", pictureSuffix);
        SkFILEWStream stream(path.c_str());
        pict->serialize(&stream);
    }

    if (FLAGS_rtree) {
        const char renderModeDescriptor[] = "-rtree";
        if ((gmFlags & GM::kSkipPicture_Flag) || (gmFlags & GM::kSkipTiled_Flag)) {
            gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                     renderModeDescriptor);
            errorsForAllModes.add(kIntentionallySkipped_ErrorType);
        } else {
            SkPicture* pict = gmmain.generate_new_picture(gm, kRTree_BbhType, 0);
            SkAutoUnref aur(pict);
            SkBitmap bitmap;
            gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap);
            errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
                gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
                &comparisonBitmap));
        }
    }

    if (FLAGS_quadtree) {
        const char renderModeDescriptor[] = "-quadtree";
        if ((gmFlags & GM::kSkipPicture_Flag) || (gmFlags & GM::kSkipTiled_Flag)) {
            gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                     renderModeDescriptor);
            errorsForAllModes.add(kIntentionallySkipped_ErrorType);
        } else {
            SkPicture* pict = gmmain.generate_new_picture(gm, kQuadTree_BbhType, 0);
            SkAutoUnref aur(pict);
            SkBitmap bitmap;
            gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap);
            errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
                gm->getName(), compareConfig.fName, renderModeDescriptor, bitmap,
                &comparisonBitmap));
        }
    }

    if (FLAGS_tileGrid) {
        for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); ++scaleIndex) {
            SkScalar replayScale = tileGridReplayScales[scaleIndex];
            SkString renderModeDescriptor("-tilegrid");
            if (SK_Scalar1 != replayScale) {
                renderModeDescriptor += "-scale-";
                renderModeDescriptor.appendScalar(replayScale);
            }

            if ((gmFlags & GM::kSkipPicture_Flag) ||
                (gmFlags & GM::kSkipTiled_Flag) ||
                ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1)) {
                gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                         renderModeDescriptor.c_str());
                errorsForAllModes.add(kIntentionallySkipped_ErrorType);
            } else {
                // We record with the reciprocal scale to obtain a replay
                // result that can be validated against comparisonBitmap.
                SkScalar recordScale = SkScalarInvert(replayScale);
                SkPicture* pict = gmmain.generate_new_picture(
                    gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFlag,
                    recordScale);
                SkAutoUnref aur(pict);
                SkBitmap bitmap;
                // We cannot yet pass 'true' to generate_image_from_picture to
                // perform actual tiled rendering (see Issue 1198 -
                // https://code.google.com/p/skia/issues/detail?id=1198)
                gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap,
                                                   replayScale /*, true */);
                errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap(
                    gm->getName(), compareConfig.fName, renderModeDescriptor.c_str(), bitmap,
                    &comparisonBitmap));
            }
        }
    }

    // run the pipe centric GM steps
    if (FLAGS_pipe) {
        errorsForAllModes.add(gmmain.test_pipe_playback(gm, compareConfig, comparisonBitmap,
                                                        FLAGS_simulatePipePlaybackFailure));
        if (FLAGS_tiledPipe) {
            errorsForAllModes.add(gmmain.test_tiled_pipe_playback(gm, compareConfig,
                                                                  comparisonBitmap));
        }
    }
    return errorsForAllModes;
}


/**
 * Run this test in a number of different configs (8888, 565, PDF,
 * etc.), confirming that the resulting bitmaps match expectations
 * (which may be different for each config).
 *
 * Returns all errors encountered while doing so.
 */
ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm,
                                      const SkTDArray<size_t> &configs,
                                      const SkTDArray<const PDFRasterizerData*> &pdfRasterizers,
                                      const SkTDArray<SkScalar> &tileGridReplayScales,
                                      GrContextFactory *grFactory);
ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm,
                                      const SkTDArray<size_t> &configs,
                                      const SkTDArray<const PDFRasterizerData*> &pdfRasterizers,
                                      const SkTDArray<SkScalar> &tileGridReplayScales,
                                      GrContextFactory *grFactory) {
    const char renderModeDescriptor[] = "";
    ErrorCombination errorsForAllConfigs;
    uint32_t gmFlags = gm->getFlags();

    for (int i = 0; i < configs.count(); i++) {
        ConfigData config = gRec[configs[i]];
        const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(gm->getName(),
                                                                               config.fName);

        // Skip any tests that we don't even need to try.
        // If any of these were skipped on a per-GM basis, record them as
        // kIntentionallySkipped.
        if (kPDF_Backend == config.fBackend) {
            if (gmFlags & GM::kSkipPDF_Flag) {
                gmmain.RecordSkippedTest(shortNamePlusConfig,
                                         renderModeDescriptor,
                                         config.fBackend);
                errorsForAllConfigs.add(kIntentionallySkipped_ErrorType);
                continue;
            }
        }
        if ((gmFlags & GM::kSkip565_Flag) &&
            (kRaster_Backend == config.fBackend) &&
            (SkBitmap::kRGB_565_Config == config.fConfig)) {
            gmmain.RecordSkippedTest(shortNamePlusConfig,
                                     renderModeDescriptor,
                                     config.fBackend);
            errorsForAllConfigs.add(kIntentionallySkipped_ErrorType);
            continue;
        }
        if (((gmFlags & GM::kSkipGPU_Flag) && kGPU_Backend == config.fBackend) ||
            ((gmFlags & GM::kGPUOnly_Flag) && kGPU_Backend != config.fBackend)) {
            gmmain.RecordSkippedTest(shortNamePlusConfig,
                                     renderModeDescriptor,
                                     config.fBackend);
            errorsForAllConfigs.add(kIntentionallySkipped_ErrorType);
            continue;
        }

        // Now we know that we want to run this test and record its
        // success or failure.
        ErrorCombination errorsForThisConfig;
        GrSurface* gpuTarget = NULL;
#if SK_SUPPORT_GPU
        SkAutoTUnref<GrSurface> auGpuTarget;
        if ((errorsForThisConfig.isEmpty()) && (kGPU_Backend == config.fBackend)) {
            if (FLAGS_resetGpuContext) {
                grFactory->destroyContexts();
            }
            GrContext* gr = grFactory->get(config.fGLContextType);
            bool grSuccess = false;
            if (gr) {
                // create a render target to back the device
                GrTextureDesc desc;
                desc.fConfig = kSkia8888_GrPixelConfig;
                desc.fFlags = kRenderTarget_GrTextureFlagBit;
                desc.fWidth = gm->getISize().width();
                desc.fHeight = gm->getISize().height();
                desc.fSampleCnt = config.fSampleCnt;
                auGpuTarget.reset(gr->createUncachedTexture(desc, NULL, 0));
                if (NULL != auGpuTarget) {
                    gpuTarget = auGpuTarget;
                    grSuccess = true;
                    // Set the user specified cache limits if non-default.
                    size_t bytes;
                    int count;
                    gr->getResourceCacheLimits(&count, &bytes);
                    if (DEFAULT_CACHE_VALUE != gGpuCacheSizeBytes) {
                        bytes = static_cast<size_t>(gGpuCacheSizeBytes);
                    }
                    if (DEFAULT_CACHE_VALUE != gGpuCacheSizeCount) {
                        count = gGpuCacheSizeCount;
                    }
                    gr->setResourceCacheLimits(count, bytes);
                }
            }
            if (!grSuccess) {
                errorsForThisConfig.add(kNoGpuContext_ErrorType);
            }
        }
#endif

        SkBitmap comparisonBitmap;

        const char* writePath;
        if (FLAGS_writePath.count() == 1) {
            writePath = FLAGS_writePath[0];
        } else {
            writePath = NULL;
        }

        if (errorsForThisConfig.isEmpty()) {
            errorsForThisConfig.add(gmmain.test_drawing(gm, config, pdfRasterizers,
                                                        writePath, gpuTarget,
                                                        &comparisonBitmap));
            gmmain.RecordTestResults(errorsForThisConfig, shortNamePlusConfig, "");
        }

        // TODO: run only if gmmain.test_drawing succeeded.
        if (kRaster_Backend == config.fBackend) {
            run_multiple_modes(gmmain, gm, config, comparisonBitmap, tileGridReplayScales);
        }

        if (FLAGS_deferred && errorsForThisConfig.isEmpty() &&
            (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBackend)) {
            errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, comparisonBitmap,
                                                                 gpuTarget));
        }

        errorsForAllConfigs.add(errorsForThisConfig);
    }
    return errorsForAllConfigs;
}


/**
 * Read individual lines from a file, pushing them into the given array.
 *
 * @param filename path to the file to read
 * @param lines array of strings to add the lines to
 * @returns true if able to read lines from the file
 */
static bool read_lines_from_file(const char* filename, SkTArray<SkString> &lines) {
    SkAutoTUnref<SkStream> streamWrapper(SkStream::NewFromFile(filename));
    SkStream *stream = streamWrapper.get();
    if (!stream) {
        SkDebugf("unable to read file '%s'\n", filename);
        return false;
    }

    char c;
    SkString line;
    while (1 == stream->read(&c, 1)) {
        // If we hit either CR or LF, we've completed a line.
        //
        // TODO: If the file uses both CR and LF, this will return an extra blank
        // line for each line of the file.  Which is OK for current purposes...
        //
        // TODO: Does this properly handle unicode?  It doesn't matter for
        // current purposes...
        if ((c == 0x0d) || (c == 0x0a)) {
            lines.push_back(line);
            line.reset();
        } else {
            line.append(&c, 1);
        }
    }
    lines.push_back(line);
    return true;
}

/**
 * Return a list of all entries in an array of strings as a single string
 * of this form:
 * "item1", "item2", "item3"
 */
SkString list_all(const SkTArray<SkString> &stringArray);
SkString list_all(const SkTArray<SkString> &stringArray) {
    SkString total;
    for (int i = 0; i < stringArray.count(); i++) {
        if (i > 0) {
            total.append(", ");
        }
        total.append("\"");
        total.append(stringArray[i]);
        total.append("\"");
    }
    return total;
}

/**
 * Return a list of configuration names, as a single string of this form:
 * "item1", "item2", "item3"
 *
 * @param configs configurations, as a list of indices into gRec
 */
SkString list_all_config_names(const SkTDArray<size_t> &configs);
SkString list_all_config_names(const SkTDArray<size_t> &configs) {
    SkString total;
    for (int i = 0; i < configs.count(); i++) {
        if (i > 0) {
            total.append(", ");
        }
        total.append("\"");
        total.append(gRec[configs[i]].fName);
        total.append("\"");
    }
    return total;
}

static bool prepare_subdirectories(const char *root, bool useFileHierarchy,
                                   const SkTDArray<size_t> &configs,
                                   const SkTDArray<const PDFRasterizerData*>& pdfRasterizers) {
    if (!sk_mkdir(root)) {
        return false;
    }
    if (useFileHierarchy) {
        for (int i = 0; i < configs.count(); i++) {
            ConfigData config = gRec[configs[i]];
            SkString subdir;
            subdir.appendf("%s%c%s", root, SkPATH_SEPARATOR, config.fName);
            if (!sk_mkdir(subdir.c_str())) {
                return false;
            }

            if (config.fBackend == kPDF_Backend) {
                for (int j = 0; j < pdfRasterizers.count(); j++) {
                    SkString pdfSubdir = subdir;
                    pdfSubdir.appendf("-%s", pdfRasterizers[j]->fName);
                    if (!sk_mkdir(pdfSubdir.c_str())) {
                        return false;
                    }
                }
            }
        }
    }
    return true;
}

static bool parse_flags_configs(SkTDArray<size_t>* outConfigs,
                         GrContextFactory* grFactory) {
    SkTDArray<size_t> excludeConfigs;

    for (int i = 0; i < FLAGS_config.count(); i++) {
        const char* config = FLAGS_config[i];
        bool exclude = false;
        if (*config == kExcludeConfigChar) {
            exclude = true;
            config += 1;
        }
        int index = findConfig(config);
        if (index >= 0) {
            if (exclude) {
                *excludeConfigs.append() = index;
            } else {
                appendUnique<size_t>(outConfigs, index);
            }
        } else if (0 == strcmp(kDefaultsConfigStr, config)) {
            if (exclude) {
                SkDebugf("%c%s is not allowed.\n",
                         kExcludeConfigChar, kDefaultsConfigStr);
                return false;
            }
            for (size_t c = 0; c < SK_ARRAY_COUNT(gRec); ++c) {
                if (gRec[c].fRunByDefault) {
                    appendUnique<size_t>(outConfigs, c);
                }
            }
        } else {
            SkDebugf("unrecognized config %s\n", config);
            return false;
        }
    }

    for (int i = 0; i < FLAGS_excludeConfig.count(); i++) {
        int index = findConfig(FLAGS_excludeConfig[i]);
        if (index >= 0) {
            *excludeConfigs.append() = index;
        } else {
            SkDebugf("unrecognized excludeConfig %s\n", FLAGS_excludeConfig[i]);
            return false;
        }
    }

    if (outConfigs->count() == 0) {
        // if no config is specified by user, add the defaults
        for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
            if (gRec[i].fRunByDefault) {
                *outConfigs->append() = i;
            }
        }
    }
    // now remove any explicitly excluded configs
    for (int i = 0; i < excludeConfigs.count(); ++i) {
        int index = outConfigs->find(excludeConfigs[i]);
        if (index >= 0) {
            outConfigs->remove(index);
            // now assert that there was only one copy in configs[]
            SkASSERT(outConfigs->find(excludeConfigs[i]) < 0);
        }
    }

#if SK_SUPPORT_GPU
    SkASSERT(grFactory != NULL);
    for (int i = 0; i < outConfigs->count(); ++i) {
        size_t index = (*outConfigs)[i];
        if (kGPU_Backend == gRec[index].fBackend) {
            GrContext* ctx = grFactory->get(gRec[index].fGLContextType);
            if (NULL == ctx) {
                SkDebugf("GrContext could not be created for config %s. Config will be skipped.\n",
                         gRec[index].fName);
                outConfigs->remove(i);
                --i;
                continue;
            }
            if (gRec[index].fSampleCnt > ctx->getMaxSampleCount()) {
                SkDebugf("Sample count (%d) of config %s is not supported."
                         " Config will be skipped.\n",
                         gRec[index].fSampleCnt, gRec[index].fName);
                outConfigs->remove(i);
                --i;
            }
        }
    }
#endif

    if (outConfigs->isEmpty()) {
        SkDebugf("No configs to run.");
        return false;
    }

    // now show the user the set of configs that will be run.
    SkString configStr("These configs will be run:");
    // show the user the config that will run.
    for (int i = 0; i < outConfigs->count(); ++i) {
        configStr.appendf(" %s", gRec[(*outConfigs)[i]].fName);
    }
    SkDebugf("%s\n", configStr.c_str());

    return true;
}

static bool parse_flags_pdf_rasterizers(const SkTDArray<size_t>& configs,
                                        SkTDArray<const PDFRasterizerData*>* outRasterizers) {
    // No need to run this check (and display the PDF rasterizers message)
    // if no PDF backends are in the configs.
    bool configHasPDF = false;
    for (int i = 0; i < configs.count(); i++) {
        if (gRec[configs[i]].fBackend == kPDF_Backend) {
            configHasPDF = true;
            break;
        }
    }
    if (!configHasPDF) {
        return true;
    }

    if (FLAGS_pdfRasterizers.count() == 1 &&
            !strcmp(FLAGS_pdfRasterizers[0], "default")) {
        for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) {
            if (kPDFRasterizers[i].fRunByDefault) {
                *outRasterizers->append() = &kPDFRasterizers[i];
            }
        }
    } else {
        for (int i = 0; i < FLAGS_pdfRasterizers.count(); i++) {
            const char* rasterizer = FLAGS_pdfRasterizers[i];
            const PDFRasterizerData* rasterizerPtr =
                    findPDFRasterizer(rasterizer);
            if (rasterizerPtr == NULL) {
                SkDebugf("unrecognized rasterizer %s\n", rasterizer);
                return false;
            }
            appendUnique<const PDFRasterizerData*>(outRasterizers,
                                                   rasterizerPtr);
        }
    }

    // now show the user the set of configs that will be run.
    SkString configStr("These PDF rasterizers will be run:");
    // show the user the config that will run.
    for (int i = 0; i < outRasterizers->count(); ++i) {
        configStr.appendf(" %s", (*outRasterizers)[i]->fName);
    }
    SkDebugf("%s\n", configStr.c_str());

    return true;
}

static bool parse_flags_ignore_error_types(ErrorCombination* outErrorTypes) {
    if (FLAGS_ignoreErrorTypes.count() > 0) {
        *outErrorTypes = ErrorCombination();
        for (int i = 0; i < FLAGS_ignoreErrorTypes.count(); i++) {
            ErrorType type;
            const char *name = FLAGS_ignoreErrorTypes[i];
            if (!getErrorTypeByName(name, &type)) {
                SkDebugf("cannot find ErrorType with name '%s'\n", name);
                return false;
            } else {
                outErrorTypes->add(type);
            }
        }
    }
    return true;
}

/**
 * Replace contents of ignoreTestNames with a list of test names, indicating
 * which tests' failures should be ignored.
 */
static bool parse_flags_ignore_tests(SkTArray<SkString> &ignoreTestNames) {
    ignoreTestNames.reset();

    // Parse --ignoreFailuresFile
    for (int i = 0; i < FLAGS_ignoreFailuresFile.count(); i++) {
        SkTArray<SkString> linesFromFile;
        if (!read_lines_from_file(FLAGS_ignoreFailuresFile[i], linesFromFile)) {
            return false;
        } else {
            for (int j = 0; j < linesFromFile.count(); j++) {
                SkString thisLine = linesFromFile[j];
                if (thisLine.isEmpty() || thisLine.startsWith('#')) {
                    // skip this line
                } else {
                    ignoreTestNames.push_back(thisLine);
                }
            }
        }
    }

    return true;
}

static bool parse_flags_modulo(int* moduloRemainder, int* moduloDivisor) {
    if (FLAGS_modulo.count() == 2) {
        *moduloRemainder = atoi(FLAGS_modulo[0]);
        *moduloDivisor = atoi(FLAGS_modulo[1]);
        if (*moduloRemainder < 0 || *moduloDivisor <= 0 ||
                *moduloRemainder >= *moduloDivisor) {
            SkDebugf("invalid modulo values.");
            return false;
        }
    }
    return true;
}

#if SK_SUPPORT_GPU
static bool parse_flags_gpu_cache(int* sizeBytes, int* sizeCount) {
    if (FLAGS_gpuCacheSize.count() > 0) {
        if (FLAGS_gpuCacheSize.count() != 2) {
            SkDebugf("--gpuCacheSize requires two arguments\n");
            return false;
        }
        *sizeBytes = atoi(FLAGS_gpuCacheSize[0]);
        *sizeCount = atoi(FLAGS_gpuCacheSize[1]);
    } else {
        *sizeBytes = DEFAULT_CACHE_VALUE;
        *sizeCount = DEFAULT_CACHE_VALUE;
    }
    return true;
}
#endif

static bool parse_flags_tile_grid_replay_scales(SkTDArray<SkScalar>* outScales) {
    *outScales->append() = SK_Scalar1; // By default only test at scale 1.0
    if (FLAGS_tileGridReplayScales.count() > 0) {
        outScales->reset();
        for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) {
            double val = atof(FLAGS_tileGridReplayScales[i]);
            if (0 < val) {
                *outScales->append() = SkDoubleToScalar(val);
            }
        }
        if (0 == outScales->count()) {
            // Should have at least one scale
            SkDebugf("--tileGridReplayScales requires at least one scale.\n");
            return false;
        }
    }
    return true;
}

static bool parse_flags_gmmain_paths(GMMain* gmmain) {
    gmmain->fUseFileHierarchy = FLAGS_hierarchy;
    gmmain->fWriteChecksumBasedFilenames = FLAGS_writeChecksumBasedFilenames;

    if (FLAGS_mismatchPath.count() == 1) {
        gmmain->fMismatchPath = FLAGS_mismatchPath[0];
    }

    if (FLAGS_missingExpectationsPath.count() == 1) {
        gmmain->fMissingExpectationsPath = FLAGS_missingExpectationsPath[0];
    }

    if (FLAGS_readPath.count() == 1) {
        const char* readPath = FLAGS_readPath[0];
        if (!sk_exists(readPath)) {
            SkDebugf("readPath %s does not exist!\n", readPath);
            return false;
        }
        if (sk_isdir(readPath)) {
            if (FLAGS_verbose) {
                SkDebugf("reading from %s\n", readPath);
            }
            gmmain->fExpectationsSource.reset(SkNEW_ARGS(
                IndividualImageExpectationsSource, (readPath)));
        } else {
#ifdef SK_BUILD_JSON_WRITER
            if (FLAGS_verbose) {
                SkDebugf("reading expectations from JSON summary file %s\n", readPath);
            }
            gmmain->fExpectationsSource.reset(SkNEW_ARGS(JsonExpectationsSource, (readPath)));
#endif
        }
    }
    return true;
}

static bool parse_flags_resource_path() {
    if (FLAGS_resourcePath.count() == 1) {
        GM::SetResourcePath(FLAGS_resourcePath[0]);
    }
    return true;
}

static bool parse_flags_jpeg_quality() {
    if (FLAGS_pdfJpegQuality < -1 || FLAGS_pdfJpegQuality > 100) {
        SkDebugf("%s\n", "pdfJpegQuality must be in [-1 .. 100] range.");
        return false;
    }
    return true;
}

int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {

    SkString usage;
    usage.printf("Run the golden master tests.\n");
    SkCommandLineFlags::SetUsage(usage.c_str());
    SkCommandLineFlags::Parse(argc, argv);

#if SK_ENABLE_INST_COUNT
    if (FLAGS_leaks) {
        gPrintInstCount = true;
    }
#endif

    SkGraphics::Init();

    setSystemPreferences();
    GMMain gmmain;

    SkTDArray<size_t> configs;

    int moduloRemainder = -1;
    int moduloDivisor = -1;
    SkTDArray<const PDFRasterizerData*> pdfRasterizers;
    SkTDArray<SkScalar> tileGridReplayScales;
#if SK_SUPPORT_GPU
    GrContextFactory* grFactory = new GrContextFactory;
#else
    GrContextFactory* grFactory = NULL;
#endif

    if (FLAGS_dryRun) {
        SkDebugf( "Doing a dry run; no tests will actually be executed.\n");
    }

    if (!parse_flags_modulo(&moduloRemainder, &moduloDivisor) ||
        !parse_flags_ignore_error_types(&gmmain.fIgnorableErrorTypes) ||
        !parse_flags_ignore_tests(gmmain.fIgnorableTestNames) ||
#if SK_SUPPORT_GPU
        !parse_flags_gpu_cache(&gGpuCacheSizeBytes, &gGpuCacheSizeCount) ||
#endif
        !parse_flags_tile_grid_replay_scales(&tileGridReplayScales) ||
        !parse_flags_resource_path() ||
        !parse_flags_jpeg_quality() ||
        !parse_flags_configs(&configs, grFactory) ||
        !parse_flags_pdf_rasterizers(configs, &pdfRasterizers) ||
        !parse_flags_gmmain_paths(&gmmain)) {
        return -1;
    }

    if (FLAGS_verbose) {
        if (FLAGS_writePath.count() == 1) {
            SkDebugf("writing to %s\n", FLAGS_writePath[0]);
        }
        if (NULL != gmmain.fMismatchPath) {
            SkDebugf("writing mismatches to %s\n", gmmain.fMismatchPath);
        }
        if (NULL != gmmain.fMissingExpectationsPath) {
            SkDebugf("writing images without expectations to %s\n",
                     gmmain.fMissingExpectationsPath);
        }
        if (FLAGS_writePicturePath.count() == 1) {
            SkDebugf("writing pictures to %s\n", FLAGS_writePicturePath[0]);
        }
        if (FLAGS_resourcePath.count() == 1) {
            SkDebugf("reading resources from %s\n", FLAGS_resourcePath[0]);
        }
    }

    int gmsRun = 0;
    int gmIndex = -1;
    SkString moduloStr;

    if (!FLAGS_dryRun) {
        // If we will be writing out files, prepare subdirectories.
        if (FLAGS_writePath.count() == 1) {
            if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy,
                                        configs, pdfRasterizers)) {
                return -1;
            }
        }
        if (NULL != gmmain.fMismatchPath) {
            if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarchy,
                                        configs, pdfRasterizers)) {
                return -1;
            }
        }
        if (NULL != gmmain.fMissingExpectationsPath) {
            if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUseFileHierarchy,
                                        configs, pdfRasterizers)) {
                return -1;
            }
        }
    }
    Iter iter;
    GM* gm;
    while ((gm = iter.next()) != NULL) {
        if (FLAGS_forcePerspectiveMatrix) {
            SkMatrix perspective;
            perspective.setIdentity();
            perspective.setPerspY(SkScalarDiv(SK_Scalar1, SkIntToScalar(1000)));
            perspective.setSkewX(SkScalarDiv(SkIntToScalar(8),
                                 SkIntToScalar(25)));

            gm->setStarterMatrix(perspective);
        }
        SkAutoTDelete<GM> adgm(gm);
        ++gmIndex;
        if (moduloRemainder >= 0) {
            if ((gmIndex % moduloDivisor) != moduloRemainder) {
                continue;
            }
            moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor);
        }

        const char* shortName = gm->getName();

        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, shortName)) {
            continue;
        }

        gmsRun++;
        SkISize size = gm->getISize();
        SkDebugf("%sdrawing... %s [%d %d]\n", moduloStr.c_str(), shortName,
                 size.width(), size.height());
        if (!FLAGS_dryRun)
            run_multiple_configs(gmmain, gm, configs, pdfRasterizers, tileGridReplayScales, grFactory);
    }

    if (FLAGS_dryRun)
        return 0;

    SkTArray<SkString> modes;
    gmmain.GetRenderModesEncountered(modes);
    int modeCount = modes.count();

    // Now that we have run all the tests and thus know the full set of renderModes that we
    // tried to run, we can call RecordTestResults() to record the cases in which we skipped
    // ALL renderModes.
    // See http://skbug.com/1994 and https://codereview.chromium.org/129203002/
    int testCount = gmmain.fTestsSkippedOnAllRenderModes.count();
    for (int testNum = 0; testNum < testCount; ++testNum) {
        const SkString &shortNamePlusConfig = gmmain.fTestsSkippedOnAllRenderModes[testNum];
        for (int modeNum = 0; modeNum < modeCount; ++modeNum) {
            gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNamePlusConfig,
                                     modes[modeNum].c_str());
        }
    }

    bool reportError = false;
    if (gmmain.NumSignificantErrors() > 0) {
        reportError = true;
    }

    // We test every GM against every config, and for every raster config also test every mode.
    int rasterConfigs = 0;
    for (int i = 0; i < configs.count(); i++) {
        if (gRec[configs[i]].fBackend == kRaster_Backend) {
            rasterConfigs++;
        }
    }
    // For raster configs, we run all renderModes; for non-raster configs, just default renderMode
    const int expectedNumberOfTests = rasterConfigs * gmsRun * modeCount
                                    + (configs.count() - rasterConfigs) * gmsRun;

    // Output summary to stdout.
    if (FLAGS_verbose) {
        SkDebugf("Ran %d GMs\n", gmsRun);
        SkDebugf("... over %2d configs [%s]\n", configs.count(),
                 list_all_config_names(configs).c_str());
        SkDebugf("...  and %2d modes   [%s]\n", modeCount, list_all(modes).c_str());
        SkDebugf("... so there should be a total of %d tests.\n", expectedNumberOfTests);
    }
    gmmain.ListErrors(FLAGS_verbose);

    // TODO(epoger): Enable this check for Android, too, once we resolve
    // https://code.google.com/p/skia/issues/detail?id=1222
    // ('GM is unexpectedly skipping tests on Android')
#ifndef SK_BUILD_FOR_ANDROID
    if (expectedNumberOfTests != gmmain.fTestsRun) {
        SkDebugf("expected %d tests, but ran or skipped %d tests\n",
                 expectedNumberOfTests, gmmain.fTestsRun);
        reportError = true;
    }
#endif

#ifdef SK_BUILD_JSON_WRITER
    if (FLAGS_writeJsonSummaryPath.count() == 1) {
        Json::Value root = CreateJsonTree(
            gmmain.fJsonExpectedResults,
            gmmain.fJsonActualResults_Failed, gmmain.fJsonActualResults_FailureIgnored,
            gmmain.fJsonActualResults_NoComparison, gmmain.fJsonActualResults_Succeeded);
        std::string jsonStdString = root.toStyledString();
        SkFILEWStream stream(FLAGS_writeJsonSummaryPath[0]);
        stream.write(jsonStdString.c_str(), jsonStdString.length());
    }
#endif

#if SK_SUPPORT_GPU

#if GR_CACHE_STATS
    for (int i = 0; i < configs.count(); i++) {
        ConfigData config = gRec[configs[i]];

        if (FLAGS_verbose && (kGPU_Backend == config.fBackend)) {
            GrContext* gr = grFactory->get(config.fGLContextType);

            SkDebugf("config: %s %x\n", config.fName, gr);
            gr->printCacheStats();
        }
    }
#endif

#if GR_DUMP_FONT_CACHE
    for (int i = 0; i < configs.count(); i++) {
        ConfigData config = gRec[configs[i]];

        if (kGPU_Backend == config.fBackend) {
            GrContext* gr = grFactory->get(config.fGLContextType);

           gr->dumpFontCache();
        }
    }
#endif

    delete grFactory;
#endif
    SkGraphics::Term();

    return (reportError) ? -1 : 0;
}

void GMMain::installFilter(SkCanvas* canvas) {
    if (FLAGS_forceBWtext) {
        canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref();
    }
}

#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
int main(int argc, char * const argv[]) {
    return tool_main(argc, (char**) argv);
}
#endif
