blob: 996737f2eed6e3ac1ce89411c8fde4b4e9e4aa02 [file] [log] [blame]
zachr@google.com945708a2013-07-02 19:55:32 +00001/*
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
djsollen@google.comefc51b72013-11-12 18:29:17 +000011#include "SkImageDiffer.h"
zachr@google.com945708a2013-07-02 19:55:32 +000012#include "SkString.h"
13#include "SkTArray.h"
14#include "SkTDArray.h"
djsollen@google.comefc51b72013-11-12 18:29:17 +000015#include "SkTLList.h"
16#include "SkThread.h"
zachr@google.com945708a2013-07-02 19:55:32 +000017
18class SkWStream;
zachr@google.com945708a2013-07-02 19:55:32 +000019
20/**
21 * Collects records of diffs and outputs them as JSON.
22 */
23class SkDiffContext {
24public:
25 SkDiffContext();
26 ~SkDiffContext();
27
djsollen@google.comcbbf1ca2013-10-16 18:36:49 +000028 void setThreadCount(int threadCount) { fThreadCount = threadCount; }
29
zachr@google.com945708a2013-07-02 19:55:32 +000030 /**
epoger54f1ad82014-07-02 07:43:04 -070031 * Sets the directory within which to store alphaMasks (images that
32 * are transparent for each pixel that differs between baseline and test).
33 *
34 * If the directory does not exist yet, it will be created.
djsollen@google.com513a7bf2013-11-07 19:24:06 +000035 */
epoger54f1ad82014-07-02 07:43:04 -070036 void setAlphaMaskDir(const SkString& directory);
37
38 /**
39 * Sets the directory within which to store rgbDiffs (images showing the
40 * per-channel difference between baseline and test at each pixel).
41 *
42 * If the directory does not exist yet, it will be created.
43 */
44 void setRgbDiffDir(const SkString& directory);
45
46 /**
47 * Sets the directory within which to store whiteDiffs (images showing white
48 * for each pixel that differs between baseline and test).
49 *
50 * If the directory does not exist yet, it will be created.
51 */
52 void setWhiteDiffDir(const SkString& directory);
djsollen@google.com513a7bf2013-11-07 19:24:06 +000053
54 /**
zachr@google.com945708a2013-07-02 19:55:32 +000055 * Sets the differs to be used in each diff. Already started diffs will not retroactively use
56 * these.
57 * @param differs An array of differs to use. The array is copied, but not the differs
58 * themselves.
59 */
60 void setDiffers(const SkTDArray<SkImageDiffer*>& differs);
61
62 /**
63 * Compares two directories of images with the given differ
64 * @param baselinePath The baseline directory's path
65 * @param testPath The test directory's path
66 */
67 void diffDirectories(const char baselinePath[], const char testPath[]);
68
69 /**
70 * Compares two sets of images identified by glob style patterns with the given differ
71 * @param baselinePattern A pattern for baseline files
72 * @param testPattern A pattern for test files that matches each file of the baseline file
73 */
74 void diffPatterns(const char baselinePattern[], const char testPattern[]);
75
76 /**
77 * Compares the images at the given paths
78 * @param baselinePath The baseline file path
79 * @param testPath The matching test file path
80 */
81 void addDiff(const char* baselinePath, const char* testPath);
82
83 /**
84 * Output the records of each diff in JSON.
85 *
86 * The format of the JSON document is one top level array named "records".
djsollen@google.comefc51b72013-11-12 18:29:17 +000087 * Each record in the array is an object with the following values:
88 * "commonName" : string containing the common prefix of the baselinePath
89 * and testPath filenames
90 * "baselinePath" : string containing the path to the baseline image
91 * "testPath" : string containing the path to the test image
92 * "differencePath" : (optional) string containing the path to an alpha
93 * mask of the pixel difference between the baseline
94 * and test images
epoger54f1ad82014-07-02 07:43:04 -070095 * TODO(epoger): consider renaming this "alphaMaskPath"
96 * to distinguish from other difference types?
97 * "rgbDiffPath" : (optional) string containing the path to a bitmap
98 * showing per-channel differences between the
99 * baseline and test images at each pixel
100 * "whiteDiffPath" : (optional) string containing the path to a bitmap
101 * showing every pixel that differs between the
102 * baseline and test images as white
djsollen@google.comefc51b72013-11-12 18:29:17 +0000103 *
zachr@google.com945708a2013-07-02 19:55:32 +0000104 * They also have an array named "diffs" with each element being one diff record for the two
105 * images indicated in the above field.
106 * A diff record includes:
107 * "differName" : string name of the diff metric used
108 * "result" : numerical result of the diff
zachr@google.com945708a2013-07-02 19:55:32 +0000109 *
110 * Here is an example:
111 *
112 * {
113 * "records": [
114 * {
djsollen@google.comefc51b72013-11-12 18:29:17 +0000115 * "commonName": "queue.png",
116 * "baselinePath": "/a/queue.png",
117 * "testPath": "/b/queue.png",
zachr@google.com945708a2013-07-02 19:55:32 +0000118 * "diffs": [
119 * {
120 * "differName": "different_pixels",
121 * "result": 1,
zachr@google.com945708a2013-07-02 19:55:32 +0000122 * }
123 * ]
124 * }
125 * ]
126 * }
127 *
zachr@google.coma95959c2013-07-08 15:04:45 +0000128 * @param stream The stream to output the diff to
129 * @param useJSONP True to adding padding to the JSON output to make it cross-site requestable.
zachr@google.com945708a2013-07-02 19:55:32 +0000130 */
zachr@google.coma95959c2013-07-08 15:04:45 +0000131 void outputRecords(SkWStream& stream, bool useJSONP);
zachr@google.com945708a2013-07-02 19:55:32 +0000132
edisonn@google.comc93c8ac2013-07-22 15:24:26 +0000133 /**
134 * Output the records score in csv format.
135 */
136 void outputCsv(SkWStream& stream);
137
138
zachr@google.com945708a2013-07-02 19:55:32 +0000139private:
140 struct DiffData {
141 const char* fDiffName;
djsollen@google.comefc51b72013-11-12 18:29:17 +0000142 SkImageDiffer::Result fResult;
zachr@google.com945708a2013-07-02 19:55:32 +0000143 };
144
145 struct DiffRecord {
epoger54f1ad82014-07-02 07:43:04 -0700146 // TODO(djsollen): Some of these fields are required, while others are optional
147 // (e.g., fRgbDiffPath is only filled in if SkDifferentPixelsMetric
148 // was run). Figure out a way to note that. See http://skbug.com/2712
149 // ('allow skpdiff to report different sets of result fields for
150 // different comparison algorithms')
djsollen@google.com513a7bf2013-11-07 19:24:06 +0000151 SkString fCommonName;
epoger54f1ad82014-07-02 07:43:04 -0700152 SkString fAlphaMaskPath;
153 SkString fRgbDiffPath;
154 SkString fWhiteDiffPath;
zachr@google.com945708a2013-07-02 19:55:32 +0000155 SkString fBaselinePath;
156 SkString fTestPath;
epoger54f1ad82014-07-02 07:43:04 -0700157 SkISize fSize;
158 int fMaxRedDiff;
159 int fMaxGreenDiff;
160 int fMaxBlueDiff;
zachr@google.com945708a2013-07-02 19:55:32 +0000161 SkTArray<DiffData> fDiffs;
zachr@google.com945708a2013-07-02 19:55:32 +0000162 };
163
djsollen@google.comefc51b72013-11-12 18:29:17 +0000164 // Used to protect access to fRecords and ensure only one thread is
165 // adding new entries at a time.
166 SkMutex fRecordMutex;
167
zachr@google.com945708a2013-07-02 19:55:32 +0000168 // We use linked list for the records so that their pointers remain stable. A resizable array
169 // might change its pointers, which would make it harder for async diffs to record their
170 // results.
djsollen@google.comefc51b72013-11-12 18:29:17 +0000171 SkTLList<DiffRecord> fRecords;
zachr@google.com945708a2013-07-02 19:55:32 +0000172
173 SkImageDiffer** fDiffers;
174 int fDifferCount;
djsollen@google.comcbbf1ca2013-10-16 18:36:49 +0000175 int fThreadCount;
djsollen@google.com513a7bf2013-11-07 19:24:06 +0000176
epoger54f1ad82014-07-02 07:43:04 -0700177 SkString fAlphaMaskDir;
178 SkString fRgbDiffDir;
179 SkString fWhiteDiffDir;
zachr@google.com945708a2013-07-02 19:55:32 +0000180};
181
182#endif