Chromium Code Reviews| 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 |