fix multithread related crashes in skpdiff

BUG=skia:1798
R=mtklein@google.com, scroggo@google.com

Review URL: https://codereview.chromium.org/60833002

git-svn-id: http://skia.googlecode.com/svn/trunk@12252 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp b/tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp
index a3e4a38..27c7a13 100644
--- a/tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp
+++ b/tools/skpdiff/SkDifferentPixelsMetric_cpu.cpp
@@ -5,60 +5,39 @@
  * found in the LICENSE file.
  */
 
-#include <cstring>
+#include "SkDifferentPixelsMetric.h"
 
 #include "SkBitmap.h"
-
-#include "SkDifferentPixelsMetric.h"
 #include "skpdiff_util.h"
 
-struct SkDifferentPixelsMetric::QueuedDiff {
-    bool finished;
-    double result;
-    SkTDArray<SkIPoint>* poi;
-    SkBitmap poiAlphaMask;
-};
-
-const char* SkDifferentPixelsMetric::getName() {
+const char* SkDifferentPixelsMetric::getName() const {
     return "different_pixels";
 }
 
-bool SkDifferentPixelsMetric::enablePOIAlphaMask() {
-    fPOIAlphaMask = true;
-    return true;
-}
-
-int SkDifferentPixelsMetric::queueDiff(SkBitmap* baseline, SkBitmap* test) {
+bool SkDifferentPixelsMetric::diff(SkBitmap* baseline, SkBitmap* test, bool computeMask,
+                                   Result* result) const {
     double startTime = get_seconds();
-    int diffID = fQueuedDiffs.count();
-    QueuedDiff* diff = fQueuedDiffs.push();
-    SkTDArray<SkIPoint>* poi = diff->poi = new SkTDArray<SkIPoint>();
-
-    // If we never end up running the kernel, include some safe defaults in the result.
-    diff->finished = false;
-    diff->result = -1;
 
     // Ensure the images are comparable
     if (baseline->width() != test->width() || baseline->height() != test->height() ||
         baseline->width() <= 0 || baseline->height() <= 0 ||
         baseline->config() != test->config()) {
-        diff->finished = true;
-        return diffID;
+        return false;
     }
 
     int width = baseline->width();
     int height = baseline->height();
-    int differentPixelsCount = 0;
 
     // Prepare the POI alpha mask if needed
-    if (fPOIAlphaMask) {
-        diff->poiAlphaMask.setConfig(SkBitmap::kA8_Config, width, height);
-        diff->poiAlphaMask.allocPixels();
-        diff->poiAlphaMask.lockPixels();
-        diff->poiAlphaMask.eraseARGB(SK_AlphaOPAQUE, 0, 0, 0);
+    if (computeMask) {
+        result->poiAlphaMask.setConfig(SkBitmap::kA8_Config, width, height);
+        result->poiAlphaMask.allocPixels();
+        result->poiAlphaMask.lockPixels();
+        result->poiAlphaMask.eraseARGB(SK_AlphaOPAQUE, 0, 0, 0);
     }
 
     // Prepare the pixels for comparison
+    result->poiCount = 0;
     baseline->lockPixels();
     test->lockPixels();
     for (int y = 0; y < height; y++) {
@@ -67,11 +46,10 @@
         unsigned char* testRow = (unsigned char*)test->getAddr(0, y);
         for (int x = 0; x < width; x++) {
             // Compare one pixel at a time so each differing pixel can be noted
-            if (std::memcmp(&baselineRow[x * 4], &testRow[x * 4], 4) != 0) {
-                poi->push()->set(x, y);
-                differentPixelsCount++;
-                if (fPOIAlphaMask) {
-                    *diff->poiAlphaMask.getAddr8(x,y) = SK_AlphaTRANSPARENT;
+            if (memcmp(&baselineRow[x * 4], &testRow[x * 4], 4) != 0) {
+                result->poiCount++;
+                if (computeMask) {
+                    *result->poiAlphaMask.getAddr8(x,y) = SK_AlphaTRANSPARENT;
                 }
             }
         }
@@ -79,41 +57,13 @@
     test->unlockPixels();
     baseline->unlockPixels();
 
+    if (computeMask) {
+        result->poiAlphaMask.unlockPixels();
+    }
+
     // Calculates the percentage of identical pixels
-    diff->result = 1.0 - ((double)differentPixelsCount / (width * height));
+    result->result = 1.0 - ((double)result->poiCount / (width * height));
+    result->timeElapsed = get_seconds() - startTime;
 
-    SkDebugf("Time: %f\n", (get_seconds() - startTime));
-
-    return diffID;
-}
-
-void SkDifferentPixelsMetric::deleteDiff(int id) {
-    if (NULL != fQueuedDiffs[id].poi)
-    {
-        delete fQueuedDiffs[id].poi;
-        fQueuedDiffs[id].poi = NULL;
-    }
-}
-
-bool SkDifferentPixelsMetric::isFinished(int id) {
-    return fQueuedDiffs[id].finished;
-}
-
-double SkDifferentPixelsMetric::getResult(int id) {
-    return fQueuedDiffs[id].result;
-}
-
-int SkDifferentPixelsMetric::getPointsOfInterestCount(int id) {
-    return fQueuedDiffs[id].poi->count();
-}
-
-SkIPoint* SkDifferentPixelsMetric::getPointsOfInterest(int id) {
-    return fQueuedDiffs[id].poi->begin();
-}
-
-SkBitmap* SkDifferentPixelsMetric::getPointsOfInterestAlphaMask(int id) {
-    if (fQueuedDiffs[id].poiAlphaMask.empty()) {
-        return NULL;
-    }
-    return &fQueuedDiffs[id].poiAlphaMask;
+    return true;
 }