| Index: tools/skpdiff/SkDiffContext.cpp
|
| diff --git a/tools/skpdiff/SkDiffContext.cpp b/tools/skpdiff/SkDiffContext.cpp
|
| index ce1fad9d58ccabe1f46a3702d32793d22e65f1b0..f64aeac2acd8fb974c36ba37a11d9bd95636a7ef 100644
|
| --- a/tools/skpdiff/SkDiffContext.cpp
|
| +++ b/tools/skpdiff/SkDiffContext.cpp
|
| @@ -14,28 +14,18 @@
|
| #include "SkThreadPool.h"
|
|
|
| #include "SkDiffContext.h"
|
| -#include "SkImageDiffer.h"
|
| #include "skpdiff_util.h"
|
|
|
| // Truncates the number of points of interests in JSON output to not freeze the parser
|
| static const int kMaxPOI = 100;
|
|
|
| SkDiffContext::SkDiffContext() {
|
| - fRecords = NULL;
|
| fDiffers = NULL;
|
| fDifferCount = 0;
|
| fThreadCount = SkThreadPool::kThreadPerCore;
|
| }
|
|
|
| SkDiffContext::~SkDiffContext() {
|
| - // Delete the record linked list
|
| - DiffRecord* currentRecord = fRecords;
|
| - while (NULL != currentRecord) {
|
| - DiffRecord* nextRecord = currentRecord->fNext;
|
| - SkDELETE(currentRecord);
|
| - currentRecord = nextRecord;
|
| - }
|
| -
|
| if (NULL != fDiffers) {
|
| SkDELETE_ARRAY(fDiffers);
|
| }
|
| @@ -82,6 +72,7 @@ void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) {
|
| // Load the images at the paths
|
| SkBitmap baselineBitmap;
|
| SkBitmap testBitmap;
|
| + SkAutoMutexAcquire imageLock(fImageMutex);
|
| if (!SkImageDecoder::DecodeFile(baselinePath, &baselineBitmap)) {
|
| SkDebugf("Failed to load bitmap \"%s\"\n", baselinePath);
|
| return;
|
| @@ -90,68 +81,62 @@ void SkDiffContext::addDiff(const char* baselinePath, const char* testPath) {
|
| SkDebugf("Failed to load bitmap \"%s\"\n", testPath);
|
| return;
|
| }
|
| + imageLock.release();
|
|
|
| // Setup a record for this diff
|
| - DiffRecord* newRecord = SkNEW(DiffRecord);
|
| - newRecord->fBaselinePath = baselinePath;
|
| - newRecord->fTestPath = testPath;
|
| - newRecord->fNext = fRecords;
|
| - fRecords = newRecord;
|
| + fRecordMutex.acquire();
|
| + DiffRecord* newRecord = fRecords.addToHead(DiffRecord());
|
| + fRecordMutex.release();
|
|
|
| // compute the common name
|
| SkString baseName = SkOSPath::SkBasename(baselinePath);
|
| SkString testName = SkOSPath::SkBasename(testPath);
|
| newRecord->fCommonName = get_common_prefix(baseName, testName);
|
|
|
| + newRecord->fBaselinePath = baselinePath;
|
| + newRecord->fTestPath = testPath;
|
| +
|
| bool alphaMaskPending = false;
|
| - bool alphaMaskCreated = false;
|
| +
|
| + // only enable alpha masks if a difference dir has been provided
|
| + if (!fDifferenceDir.isEmpty()) {
|
| + alphaMaskPending = true;
|
| + }
|
|
|
| // Perform each diff
|
| for (int differIndex = 0; differIndex < fDifferCount; differIndex++) {
|
| SkImageDiffer* differ = fDiffers[differIndex];
|
| - // TODO only enable for one differ
|
| - if (!alphaMaskCreated && !fDifferenceDir.isEmpty()) {
|
| - alphaMaskPending = differ->enablePOIAlphaMask();
|
| +
|
| + // Copy the results into data for this record
|
| + DiffData& diffData = newRecord->fDiffs.push_back();
|
| + diffData.fDiffName = differ->getName();
|
| +
|
| + if (!differ->diff(&baselineBitmap, &testBitmap, alphaMaskPending, &diffData.fResult)) {
|
| + // if the diff failed the remove its entry from the list
|
| + newRecord->fDiffs.pop_back();
|
| + continue;
|
| }
|
| - int diffID = differ->queueDiff(&baselineBitmap, &testBitmap);
|
| - if (diffID >= 0) {
|
| -
|
| - // Copy the results into data for this record
|
| - DiffData& diffData = newRecord->fDiffs.push_back();
|
| -
|
| - diffData.fDiffName = differ->getName();
|
| - diffData.fResult = differ->getResult(diffID);
|
| -
|
| - int poiCount = differ->getPointsOfInterestCount(diffID);
|
| - SkIPoint* poi = differ->getPointsOfInterest(diffID);
|
| - diffData.fPointsOfInterest.append(poiCount, poi);
|
| -
|
| - if (alphaMaskPending
|
| - && SkImageDiffer::RESULT_CORRECT != diffData.fResult
|
| - && newRecord->fDifferencePath.isEmpty()) {
|
| - newRecord->fDifferencePath = SkOSPath::SkPathJoin(fDifferenceDir.c_str(),
|
| - newRecord->fCommonName.c_str());
|
| -
|
| - // compute the image diff and output it
|
| - SkBitmap* alphaMask = differ->getPointsOfInterestAlphaMask(diffID);
|
| - SkBitmap copy;
|
| - alphaMask->copyTo(©, SkBitmap::kARGB_8888_Config);
|
| - SkImageEncoder::EncodeFile(newRecord->fDifferencePath.c_str(), copy,
|
| - SkImageEncoder::kPNG_Type, 100);
|
| - }
|
|
|
| - if (alphaMaskPending) {
|
| - alphaMaskPending = false;
|
| - alphaMaskCreated = true;
|
| - }
|
| + if (alphaMaskPending
|
| + && SkImageDiffer::RESULT_CORRECT != diffData.fResult.result
|
| + && !diffData.fResult.poiAlphaMask.empty()
|
| + && !newRecord->fCommonName.isEmpty()) {
|
| +
|
| + newRecord->fDifferencePath = SkOSPath::SkPathJoin(fDifferenceDir.c_str(),
|
| + newRecord->fCommonName.c_str());
|
| +
|
| + // compute the image diff and output it
|
| + SkBitmap copy;
|
| + diffData.fResult.poiAlphaMask.copyTo(©, SkBitmap::kARGB_8888_Config);
|
| + SkImageEncoder::EncodeFile(newRecord->fDifferencePath.c_str(), copy,
|
| + SkImageEncoder::kPNG_Type, 100);
|
|
|
| - // Because we are doing everything synchronously for now, we are done with the diff
|
| - // after reading it.
|
| - differ->deleteDiff(diffID);
|
| + // cleanup the existing bitmap to free up resources;
|
| + diffData.fResult.poiAlphaMask.reset();
|
| +
|
| + alphaMaskPending = false;
|
| }
|
| }
|
| -
|
| - // if we get a difference and we want the alpha mask then compute it here.
|
| }
|
|
|
| class SkThreadedDiff : public SkRunnable {
|
| @@ -241,7 +226,9 @@ void SkDiffContext::diffPatterns(const char baselinePattern[], const char testPa
|
| }
|
|
|
| void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
|
| - DiffRecord* currentRecord = fRecords;
|
| + SkTLList<DiffRecord>::Iter iter(fRecords, SkTLList<DiffRecord>::Iter::kHead_IterStart);
|
| + DiffRecord* currentRecord = iter.get();
|
| +
|
| if (useJSONP) {
|
| stream.writeText("var SkPDiffRecords = {\n");
|
| } else {
|
| @@ -281,27 +268,13 @@ void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
|
| stream.writeText("\",\n");
|
|
|
| stream.writeText(" \"result\": ");
|
| - stream.writeScalarAsText((SkScalar)data.fResult);
|
| + stream.writeScalarAsText((SkScalar)data.fResult.result);
|
| stream.writeText(",\n");
|
|
|
| - stream.writeText(" \"pointsOfInterest\": [\n");
|
| - for (int poiIndex = 0; poiIndex < data.fPointsOfInterest.count() &&
|
| - poiIndex < kMaxPOI; poiIndex++) {
|
| - SkIPoint poi = data.fPointsOfInterest[poiIndex];
|
| - stream.writeText(" [");
|
| - stream.writeDecAsText(poi.x());
|
| - stream.writeText(",");
|
| - stream.writeDecAsText(poi.y());
|
| - stream.writeText("]");
|
| -
|
| - // JSON does not allow trailing commas
|
| - if (poiIndex + 1 < data.fPointsOfInterest.count() &&
|
| - poiIndex + 1 < kMaxPOI) {
|
| - stream.writeText(",");
|
| - }
|
| - stream.writeText("\n");
|
| - }
|
| - stream.writeText(" ]\n");
|
| + stream.writeText(" \"pointsOfInterest\": ");
|
| + stream.writeDecAsText(data.fResult.poiCount);
|
| + stream.writeText("\n");
|
| +
|
| stream.writeText(" }");
|
|
|
| // JSON does not allow trailing commas
|
| @@ -314,12 +287,13 @@ void SkDiffContext::outputRecords(SkWStream& stream, bool useJSONP) {
|
|
|
| stream.writeText(" }");
|
|
|
| + currentRecord = iter.next();
|
| +
|
| // JSON does not allow trailing commas
|
| - if (NULL != currentRecord->fNext) {
|
| + if (NULL != currentRecord) {
|
| stream.writeText(",");
|
| }
|
| stream.writeText("\n");
|
| - currentRecord = currentRecord->fNext;
|
| }
|
| stream.writeText(" ]\n");
|
| if (useJSONP) {
|
| @@ -335,7 +309,8 @@ void SkDiffContext::outputCsv(SkWStream& stream) {
|
|
|
| stream.writeText("key");
|
|
|
| - DiffRecord* currentRecord = fRecords;
|
| + SkTLList<DiffRecord>::Iter iter(fRecords, SkTLList<DiffRecord>::Iter::kHead_IterStart);
|
| + DiffRecord* currentRecord = iter.get();
|
|
|
| // Write CSV header and create a dictionary of all columns.
|
| while (NULL != currentRecord) {
|
| @@ -348,14 +323,15 @@ void SkDiffContext::outputCsv(SkWStream& stream) {
|
| cntColumns++;
|
| }
|
| }
|
| - currentRecord = currentRecord->fNext;
|
| + currentRecord = iter.next();
|
| }
|
| stream.writeText("\n");
|
|
|
| double values[100];
|
| SkASSERT(cntColumns < 100); // Make the array larger, if we ever have so many diff types.
|
|
|
| - currentRecord = fRecords;
|
| + SkTLList<DiffRecord>::Iter iter2(fRecords, SkTLList<DiffRecord>::Iter::kHead_IterStart);
|
| + currentRecord = iter2.get();
|
| while (NULL != currentRecord) {
|
| for (int i = 0; i < cntColumns; i++) {
|
| values[i] = -1;
|
| @@ -366,7 +342,7 @@ void SkDiffContext::outputCsv(SkWStream& stream) {
|
| int index = -1;
|
| SkAssertResult(columns.find(data.fDiffName, &index));
|
| SkASSERT(index >= 0 && index < cntColumns);
|
| - values[index] = data.fResult;
|
| + values[index] = data.fResult.result;
|
| }
|
|
|
| const char* filename = currentRecord->fBaselinePath.c_str() +
|
| @@ -384,6 +360,6 @@ void SkDiffContext::outputCsv(SkWStream& stream) {
|
| }
|
| stream.writeText("\n");
|
|
|
| - currentRecord = currentRecord->fNext;
|
| + currentRecord = iter2.next();
|
| }
|
| }
|
|
|