OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkBitmap.h" | 8 #include "SkBitmap.h" |
9 #include "SkImageDecoder.h" | 9 #include "SkImageDecoder.h" |
10 #include "SkOSFile.h" | 10 #include "SkOSFile.h" |
11 #include "SkRunnable.h" | |
11 #include "SkStream.h" | 12 #include "SkStream.h" |
12 #include "SkTDict.h" | 13 #include "SkTDict.h" |
14 #include "SkThreadPool.h" | |
13 | 15 |
14 #include "SkDiffContext.h" | 16 #include "SkDiffContext.h" |
15 #include "SkImageDiffer.h" | 17 #include "SkImageDiffer.h" |
16 #include "skpdiff_util.h" | 18 #include "skpdiff_util.h" |
17 | 19 |
18 // Truncates the number of points of interests in JSON output to not freeze the parser | 20 // Truncates the number of points of interests in JSON output to not freeze the parser |
19 static const int kMaxPOI = 100; | 21 static const int kMaxPOI = 100; |
20 | 22 |
21 SkDiffContext::SkDiffContext() { | 23 SkDiffContext::SkDiffContext() { |
22 fRecords = NULL; | 24 fRecords = NULL; |
23 fDiffers = NULL; | 25 fDiffers = NULL; |
24 fDifferCount = 0; | 26 fDifferCount = 0; |
27 fThreadCount = SkThreadPool::kThreadPerCore; | |
25 } | 28 } |
26 | 29 |
27 SkDiffContext::~SkDiffContext() { | 30 SkDiffContext::~SkDiffContext() { |
28 // Delete the record linked list | 31 // Delete the record linked list |
29 DiffRecord* currentRecord = fRecords; | 32 DiffRecord* currentRecord = fRecords; |
30 while (NULL != currentRecord) { | 33 while (NULL != currentRecord) { |
31 DiffRecord* nextRecord = currentRecord->fNext; | 34 DiffRecord* nextRecord = currentRecord->fNext; |
32 SkDELETE(currentRecord); | 35 SkDELETE(currentRecord); |
33 currentRecord = nextRecord; | 36 currentRecord = nextRecord; |
34 } | 37 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
86 | 89 |
87 int poiCount = differ->getPointsOfInterestCount(diffID); | 90 int poiCount = differ->getPointsOfInterestCount(diffID); |
88 SkIPoint* poi = differ->getPointsOfInterest(diffID); | 91 SkIPoint* poi = differ->getPointsOfInterest(diffID); |
89 diffData.fPointsOfInterest.append(poiCount, poi); | 92 diffData.fPointsOfInterest.append(poiCount, poi); |
90 | 93 |
91 // Because we are doing everything synchronously for now, we are don e with the diff | 94 // Because we are doing everything synchronously for now, we are don e with the diff |
92 // after reading it. | 95 // after reading it. |
93 differ->deleteDiff(diffID); | 96 differ->deleteDiff(diffID); |
94 } | 97 } |
95 } | 98 } |
99 | |
100 // if we get a difference and we want the alpha mask then compute it here. | |
96 } | 101 } |
97 | 102 |
103 class SkThreadedDiff : public SkRunnable { | |
104 public: | |
105 SkThreadedDiff() : fDiffContext(NULL) { } | |
106 | |
107 void setup(SkDiffContext* diffContext, const SkString& baselinePath, const S kString& testPath) { | |
108 fDiffContext = diffContext; | |
109 fBaselinePath = baselinePath; | |
110 fTestPath = testPath; | |
111 } | |
112 | |
113 virtual void run() SK_OVERRIDE { | |
114 fDiffContext->addDiff(fBaselinePath.c_str(), fTestPath.c_str()); | |
mtklein
2013/10/23 02:47:12
I'm crashing all over the place when I run skpdiff
| |
115 } | |
116 | |
117 private: | |
118 SkDiffContext* fDiffContext; | |
119 SkString fBaselinePath; | |
120 SkString fTestPath; | |
121 }; | |
98 | 122 |
99 void SkDiffContext::diffDirectories(const char baselinePath[], const char testPa th[]) { | 123 void SkDiffContext::diffDirectories(const char baselinePath[], const char testPa th[]) { |
100 // Get the files in the baseline, we will then look for those inside the tes t path | 124 // Get the files in the baseline, we will then look for those inside the tes t path |
101 SkTArray<SkString> baselineEntries; | 125 SkTArray<SkString> baselineEntries; |
102 if (!get_directory(baselinePath, &baselineEntries)) { | 126 if (!get_directory(baselinePath, &baselineEntries)) { |
103 SkDebugf("Unable to open path \"%s\"\n", baselinePath); | 127 SkDebugf("Unable to open path \"%s\"\n", baselinePath); |
104 return; | 128 return; |
105 } | 129 } |
106 | 130 |
107 for (int baselineIndex = 0; baselineIndex < baselineEntries.count(); baselin eIndex++) { | 131 SkThreadPool threadPool(fThreadCount); |
108 SkDebugf("[%i/%i] ", baselineIndex, baselineEntries.count()); | 132 SkTArray<SkThreadedDiff> runnableDiffs; |
109 const char* baseFilename = baselineEntries[baselineIndex].c_str(); | 133 runnableDiffs.reset(baselineEntries.count()); |
134 | |
135 for (int x = 0; x < baselineEntries.count(); x++) { | |
136 const char* baseFilename = baselineEntries[x].c_str(); | |
110 | 137 |
111 // Find the real location of each file to compare | 138 // Find the real location of each file to compare |
112 SkString baselineFile = SkOSPath::SkPathJoin(baselinePath, baseFilename) ; | 139 SkString baselineFile = SkOSPath::SkPathJoin(baselinePath, baseFilename) ; |
113 SkString testFile = SkOSPath::SkPathJoin(testPath, baseFilename); | 140 SkString testFile = SkOSPath::SkPathJoin(testPath, baseFilename); |
114 | 141 |
115 // Check that the test file exists and is a file | 142 // Check that the test file exists and is a file |
116 if (sk_exists(testFile.c_str()) && !sk_isdir(testFile.c_str())) { | 143 if (sk_exists(testFile.c_str()) && !sk_isdir(testFile.c_str())) { |
117 // Queue up the comparison with the differ | 144 // Queue up the comparison with the differ |
118 this->addDiff(baselineFile.c_str(), testFile.c_str()); | 145 runnableDiffs[x].setup(this, baselineFile, testFile); |
146 threadPool.add(&runnableDiffs[x]); | |
119 } else { | 147 } else { |
120 SkDebugf("Baseline file \"%s\" has no corresponding test file\n", ba selineFile.c_str()); | 148 SkDebugf("Baseline file \"%s\" has no corresponding test file\n", ba selineFile.c_str()); |
121 } | 149 } |
122 } | 150 } |
151 | |
152 threadPool.wait(); | |
mtklein
2013/10/23 02:47:12
These wait() calls are harmless, but you can cut t
| |
123 } | 153 } |
124 | 154 |
125 | 155 |
126 void SkDiffContext::diffPatterns(const char baselinePattern[], const char testPa ttern[]) { | 156 void SkDiffContext::diffPatterns(const char baselinePattern[], const char testPa ttern[]) { |
127 // Get the files in the baseline and test patterns. Because they are in sort ed order, it's easy | 157 // Get the files in the baseline and test patterns. Because they are in sort ed order, it's easy |
128 // to find corresponding images by matching entry indices. | 158 // to find corresponding images by matching entry indices. |
129 | 159 |
130 SkTArray<SkString> baselineEntries; | 160 SkTArray<SkString> baselineEntries; |
131 if (!glob_files(baselinePattern, &baselineEntries)) { | 161 if (!glob_files(baselinePattern, &baselineEntries)) { |
132 SkDebugf("Unable to get pattern \"%s\"\n", baselinePattern); | 162 SkDebugf("Unable to get pattern \"%s\"\n", baselinePattern); |
133 return; | 163 return; |
134 } | 164 } |
135 | 165 |
136 SkTArray<SkString> testEntries; | 166 SkTArray<SkString> testEntries; |
137 if (!glob_files(testPattern, &testEntries)) { | 167 if (!glob_files(testPattern, &testEntries)) { |
138 SkDebugf("Unable to get pattern \"%s\"\n", testPattern); | 168 SkDebugf("Unable to get pattern \"%s\"\n", testPattern); |
139 return; | 169 return; |
140 } | 170 } |
141 | 171 |
142 if (baselineEntries.count() != testEntries.count()) { | 172 if (baselineEntries.count() != testEntries.count()) { |
143 SkDebugf("Baseline and test patterns do not yield corresponding number o f files\n"); | 173 SkDebugf("Baseline and test patterns do not yield corresponding number o f files\n"); |
144 return; | 174 return; |
145 } | 175 } |
146 | 176 |
147 for (int entryIndex = 0; entryIndex < baselineEntries.count(); entryIndex++) { | 177 SkThreadPool threadPool(fThreadCount); |
148 SkDebugf("[%i/%i] ", entryIndex, baselineEntries.count()); | 178 SkTArray<SkThreadedDiff> runnableDiffs; |
149 const char* baselineFilename = baselineEntries[entryIndex].c_str(); | 179 runnableDiffs.reset(baselineEntries.count()); |
150 const char* testFilename = testEntries [entryIndex].c_str(); | |
151 | 180 |
152 this->addDiff(baselineFilename, testFilename); | 181 for (int x = 0; x < baselineEntries.count(); x++) { |
182 runnableDiffs[x].setup(this, baselineEntries[x], testEntries[x]); | |
183 threadPool.add(&runnableDiffs[x]); | |
153 } | 184 } |
185 | |
186 threadPool.wait(); | |
154 } | 187 } |
155 | 188 |
156 void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) { | 189 void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) { |
157 DiffRecord* currentRecord = fRecords; | 190 DiffRecord* currentRecord = fRecords; |
158 if (useJSONP) { | 191 if (useJSONP) { |
159 stream.writeText("var SkPDiffRecords = {\n"); | 192 stream.writeText("var SkPDiffRecords = {\n"); |
160 } else { | 193 } else { |
161 stream.writeText("{\n"); | 194 stream.writeText("{\n"); |
162 } | 195 } |
163 stream.writeText(" \"records\": [\n"); | 196 stream.writeText(" \"records\": [\n"); |
164 while (NULL != currentRecord) { | 197 while (NULL != currentRecord) { |
165 stream.writeText(" {\n"); | 198 stream.writeText(" {\n"); |
166 | 199 |
200 SkString differenceAbsPath = get_absolute_path(currentRecord->fDiffe rencePath); | |
167 SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselin ePath); | 201 SkString baselineAbsPath = get_absolute_path(currentRecord->fBaselin ePath); |
168 SkString testAbsPath = get_absolute_path(currentRecord->fTestPath); | 202 SkString testAbsPath = get_absolute_path(currentRecord->fTestPath); |
169 | 203 |
170 // strip off directory structure and find the common part of the fil ename | 204 // strip off directory structure and find the common part of the fil ename |
171 SkString baseName = SkOSPath::SkBasename(baselineAbsPath.c_str()); | 205 SkString baseName = SkOSPath::SkBasename(baselineAbsPath.c_str()); |
172 SkString testName = SkOSPath::SkBasename(testAbsPath.c_str()); | 206 SkString testName = SkOSPath::SkBasename(testAbsPath.c_str()); |
173 for (size_t x = 0; x < baseName.size(); ++x) { | 207 for (size_t x = 0; x < baseName.size(); ++x) { |
174 if (baseName[x] != testName[x]) { | 208 if (baseName[x] != testName[x]) { |
175 baseName.insertUnichar(x, '\n'); | 209 baseName.insertUnichar(x, '\n'); |
176 break; | 210 break; |
177 } | 211 } |
178 } | 212 } |
179 | 213 |
180 stream.writeText(" \"commonName\": \""); | 214 stream.writeText(" \"commonName\": \""); |
181 stream.writeText(baseName.c_str()); | 215 stream.writeText(baseName.c_str()); |
182 stream.writeText("\",\n"); | 216 stream.writeText("\",\n"); |
183 | 217 |
218 stream.writeText(" \"differencePath\": \""); | |
219 stream.writeText(differenceAbsPath.c_str()); | |
220 stream.writeText("\",\n"); | |
221 | |
184 stream.writeText(" \"baselinePath\": \""); | 222 stream.writeText(" \"baselinePath\": \""); |
185 stream.writeText(baselineAbsPath.c_str()); | 223 stream.writeText(baselineAbsPath.c_str()); |
186 stream.writeText("\",\n"); | 224 stream.writeText("\",\n"); |
187 | 225 |
188 stream.writeText(" \"testPath\": \""); | 226 stream.writeText(" \"testPath\": \""); |
189 stream.writeText(testAbsPath.c_str()); | 227 stream.writeText(testAbsPath.c_str()); |
190 stream.writeText("\",\n"); | 228 stream.writeText("\",\n"); |
191 | 229 |
192 stream.writeText(" \"diffs\": [\n"); | 230 stream.writeText(" \"diffs\": [\n"); |
193 for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); d iffIndex++) { | 231 for (int diffIndex = 0; diffIndex < currentRecord->fDiffs.count(); d iffIndex++) { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
298 for (int i = 0; i < cntColumns; i++) { | 336 for (int i = 0; i < cntColumns; i++) { |
299 SkString str; | 337 SkString str; |
300 str.printf(", %f", values[i]); | 338 str.printf(", %f", values[i]); |
301 stream.writeText(str.c_str()); | 339 stream.writeText(str.c_str()); |
302 } | 340 } |
303 stream.writeText("\n"); | 341 stream.writeText("\n"); |
304 | 342 |
305 currentRecord = currentRecord->fNext; | 343 currentRecord = currentRecord->fNext; |
306 } | 344 } |
307 } | 345 } |
OLD | NEW |