Home | History | Annotate | Download | only in skpdiff
      1 /*
      2  * Copyright 2013 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SkDiffContext_DEFINED
      9 #define SkDiffContext_DEFINED
     10 
     11 #include "SkImageDiffer.h"
     12 #include "SkString.h"
     13 #include "SkTArray.h"
     14 #include "SkTDArray.h"
     15 #include "SkTLList.h"
     16 #include "SkThread.h"
     17 
     18 class SkWStream;
     19 
     20 /**
     21  * Collects records of diffs and outputs them as JSON.
     22  */
     23 class SkDiffContext {
     24 public:
     25     SkDiffContext();
     26     ~SkDiffContext();
     27 
     28     void setThreadCount(int threadCount) { fThreadCount = threadCount; }
     29 
     30     /**
     31      * Creates the directory if it does not exist and uses it to store differences
     32      * between images.
     33      */
     34     void setDifferenceDir(const SkString& directory);
     35 
     36     /**
     37      * Sets the differs to be used in each diff. Already started diffs will not retroactively use
     38      * these.
     39      * @param differs An array of differs to use. The array is copied, but not the differs
     40      *                themselves.
     41      */
     42     void setDiffers(const SkTDArray<SkImageDiffer*>& differs);
     43 
     44     /**
     45      * Compares two directories of images with the given differ
     46      * @param baselinePath The baseline directory's path
     47      * @param testPath     The test directory's path
     48      */
     49     void diffDirectories(const char baselinePath[], const char testPath[]);
     50 
     51     /**
     52      * Compares two sets of images identified by glob style patterns with the given differ
     53      * @param baselinePattern A pattern for baseline files
     54      * @param testPattern     A pattern for test files that matches each file of the baseline file
     55      */
     56     void diffPatterns(const char baselinePattern[], const char testPattern[]);
     57 
     58     /**
     59      * Compares the images at the given paths
     60      * @param baselinePath The baseline file path
     61      * @param testPath     The matching test file path
     62      */
     63     void addDiff(const char* baselinePath, const char* testPath);
     64 
     65     /**
     66      * Output the records of each diff in JSON.
     67      *
     68      * The format of the JSON document is one top level array named "records".
     69      * Each record in the array is an object with the following values:
     70      *    "commonName"     : string containing the common prefix of the baselinePath
     71      *                       and testPath filenames
     72      *    "baselinePath"   : string containing the path to the baseline image
     73      *    "testPath"       : string containing the path to the test image
     74      *    "differencePath" : (optional) string containing the path to an alpha
     75      *                       mask of the pixel difference between the baseline
     76      *                       and test images
     77      *
     78      * They also have an array named "diffs" with each element being one diff record for the two
     79      * images indicated in the above field.
     80      * A diff record includes:
     81      *    "differName"       : string name of the diff metric used
     82      *    "result"           : numerical result of the diff
     83      *
     84      * Here is an example:
     85      *
     86      * {
     87      *     "records": [
     88      *         {
     89      *             "commonName": "queue.png",
     90      *             "baselinePath": "/a/queue.png",
     91      *             "testPath": "/b/queue.png",
     92      *             "diffs": [
     93      *                 {
     94      *                     "differName": "different_pixels",
     95      *                     "result": 1,
     96      *                 }
     97      *             ]
     98      *         }
     99      *     ]
    100      * }
    101      *
    102      * @param stream   The stream to output the diff to
    103      * @param useJSONP True to adding padding to the JSON output to make it cross-site requestable.
    104      */
    105     void outputRecords(SkWStream& stream, bool useJSONP);
    106 
    107     /**
    108      * Output the records score in csv format.
    109      */
    110     void outputCsv(SkWStream& stream);
    111 
    112 
    113 private:
    114     struct DiffData {
    115         const char* fDiffName;
    116         SkImageDiffer::Result fResult;
    117     };
    118 
    119     struct DiffRecord {
    120         SkString           fCommonName;
    121         SkString           fDifferencePath;
    122         SkString           fBaselinePath;
    123         SkString               fTestPath;
    124         SkTArray<DiffData>        fDiffs;
    125     };
    126 
    127     // Used to protect access to fRecords and ensure only one thread is
    128     // adding new entries at a time.
    129     SkMutex fRecordMutex;
    130 
    131     // We use linked list for the records so that their pointers remain stable. A resizable array
    132     // might change its pointers, which would make it harder for async diffs to record their
    133     // results.
    134     SkTLList<DiffRecord> fRecords;
    135 
    136     SkImageDiffer** fDiffers;
    137     int fDifferCount;
    138     int fThreadCount;
    139 
    140     SkString fDifferenceDir;
    141 };
    142 
    143 #endif
    144