• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
setThreadCount(int threadCount)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