aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkPathOpsOp.cpp
diff options
context:
space:
mode:
authorGravatar caryclark <caryclark@google.com>2016-10-24 05:10:14 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-10-24 05:10:14 -0700
commit1326068147ee60de138061a3fc1157fcfd5d017b (patch)
tree050c8bfb9325c5b48782d09fb1246338e2343063 /src/pathops/SkPathOpsOp.cpp
parent826167111f80a4251266812cf720ad712bd29446 (diff)
formalize host debugging
Pathops writes files, anticipating upcoming crashes, and verifies the results against regions. Formalize these debugging methods so that they are more easily triggered by hosts outside of skia unit tests. TBR=reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2441763003 Review-Url: https://codereview.chromium.org/2441763003
Diffstat (limited to 'src/pathops/SkPathOpsOp.cpp')
-rw-r--r--src/pathops/SkPathOpsOp.cpp166
1 files changed, 12 insertions, 154 deletions
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
index e622451a92..f423ba9123 100644
--- a/src/pathops/SkPathOpsOp.cpp
+++ b/src/pathops/SkPathOpsOp.cpp
@@ -198,44 +198,6 @@ static const bool gOutInverse[kReverseDifference_SkPathOp + 1][2][2] = {
{{ false, true }, { false, false }}, // rev diff
};
-#define DEBUGGING_PATHOPS_FROM_HOST 0 // enable to debug svg in chrome -- note path hardcoded below
-#if DEBUGGING_PATHOPS_FROM_HOST
-#include "SkData.h"
-#include "SkStream.h"
-
-static void dump_path(FILE* file, const SkPath& path, bool force, bool dumpAsHex) {
- SkDynamicMemoryWStream wStream;
- path.dump(&wStream, force, dumpAsHex);
- sk_sp<SkData> data(wStream.detachAsData());
- fprintf(file, "%.*s\n", (int) data->size(), (char*) data->data());
-}
-
-static int dumpID = 0;
-
-static void dump_op(const SkPath& one, const SkPath& two, SkPathOp op) {
-#if SK_BUILD_FOR_MAC
- FILE* file = fopen("/Users/caryclark/Documents/svgop.txt", "w");
-#else
- FILE* file = fopen("/usr/local/google/home/caryclark/Documents/svgop.txt", "w");
-#endif
- fprintf(file,
- "\nstatic void fuzz763_%d(skiatest::Reporter* reporter, const char* filename) {\n",
- ++dumpID);
- fprintf(file, " SkPath path;\n");
- fprintf(file, " path.setFillType((SkPath::FillType) %d);\n", one.getFillType());
- dump_path(file, one, false, true);
- fprintf(file, " SkPath path1(path);\n");
- fprintf(file, " path.reset();\n");
- fprintf(file, " path.setFillType((SkPath::FillType) %d);\n", two.getFillType());
- dump_path(file, two, false, true);
- fprintf(file, " SkPath path2(path);\n");
- fprintf(file, " testPathOp(reporter, path1, path2, (SkPathOp) %d, filename);\n", op);
- fprintf(file, "}\n");
- fclose(file);
-}
-#endif
-
-
#if DEBUG_T_SECT_LOOP_COUNT
#include "SkMutex.h"
@@ -261,8 +223,10 @@ bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result
SkOpGlobalState globalState(contourList, &allocator
SkDEBUGPARAMS(skipAssert) SkDEBUGPARAMS(testName));
SkOpCoincidence coincidence(&globalState);
-#if DEBUGGING_PATHOPS_FROM_HOST
- dump_op(one, two, op);
+#ifdef SK_DEBUG
+ if (SkPathOpsDebug::gDumpOp) {
+ SkPathOpsDebug::DumpOp(one, two, op, testName);
+ }
#endif
op = gOpInverse[op][one.isInverseFillType()][two.isInverseFillType()];
SkPath::FillType fillType = gOutInverse[op][one.isInverseFillType()][two.isInverseFillType()]
@@ -351,122 +315,16 @@ bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result
return true;
}
-#define DEBUG_VERIFY 0
-
-#if DEBUG_VERIFY
-#include "SkBitmap.h"
-#include "SkCanvas.h"
-#include "SkPaint.h"
-
-const int bitWidth = 64;
-const int bitHeight = 64;
-
-static void debug_scale_matrix(const SkPath& one, const SkPath& two, SkMatrix& scale) {
- SkRect larger = one.getBounds();
- larger.join(two.getBounds());
- SkScalar largerWidth = larger.width();
- if (largerWidth < 4) {
- largerWidth = 4;
- }
- SkScalar largerHeight = larger.height();
- if (largerHeight < 4) {
- largerHeight = 4;
- }
- SkScalar hScale = (bitWidth - 2) / largerWidth;
- SkScalar vScale = (bitHeight - 2) / largerHeight;
- scale.reset();
- scale.preScale(hScale, vScale);
- larger.fLeft *= hScale;
- larger.fRight *= hScale;
- larger.fTop *= vScale;
- larger.fBottom *= vScale;
- SkScalar dx = -16000 > larger.fLeft ? -16000 - larger.fLeft
- : 16000 < larger.fRight ? 16000 - larger.fRight : 0;
- SkScalar dy = -16000 > larger.fTop ? -16000 - larger.fTop
- : 16000 < larger.fBottom ? 16000 - larger.fBottom : 0;
- scale.preTranslate(dx, dy);
-}
-
-static int debug_paths_draw_the_same(const SkPath& one, const SkPath& two, SkBitmap& bits) {
- if (bits.width() == 0) {
- bits.allocN32Pixels(bitWidth * 2, bitHeight);
- }
- SkCanvas canvas(bits);
- canvas.drawColor(SK_ColorWHITE);
- SkPaint paint;
- canvas.save();
- const SkRect& bounds1 = one.getBounds();
- canvas.translate(-bounds1.fLeft + 1, -bounds1.fTop + 1);
- canvas.drawPath(one, paint);
- canvas.restore();
- canvas.save();
- canvas.translate(-bounds1.fLeft + 1 + bitWidth, -bounds1.fTop + 1);
- canvas.drawPath(two, paint);
- canvas.restore();
- int errors = 0;
- for (int y = 0; y < bitHeight - 1; ++y) {
- uint32_t* addr1 = bits.getAddr32(0, y);
- uint32_t* addr2 = bits.getAddr32(0, y + 1);
- uint32_t* addr3 = bits.getAddr32(bitWidth, y);
- uint32_t* addr4 = bits.getAddr32(bitWidth, y + 1);
- for (int x = 0; x < bitWidth - 1; ++x) {
- // count 2x2 blocks
- bool err = addr1[x] != addr3[x];
- if (err) {
- errors += addr1[x + 1] != addr3[x + 1]
- && addr2[x] != addr4[x] && addr2[x + 1] != addr4[x + 1];
- }
+bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
+#ifdef SK_DEBUG
+ if (SkPathOpsDebug::gVerifyOp) {
+ if (!OpDebug(one, two, op, result SkDEBUGPARAMS(false) SkDEBUGPARAMS(nullptr))) {
+ SkPathOpsDebug::ReportOpFail(one, two, op);
+ return false;
}
+ SkPathOpsDebug::VerifyOp(one, two, op, *result);
+ return true;
}
- return errors;
-}
-
#endif
-
-bool Op(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result) {
-#if DEBUG_VERIFY
- if (!OpDebug(one, two, op, result SkDEBUGPARAMS(nullptr))) {
- SkDebugf("%s did not expect failure\none: fill=%d\n", __FUNCTION__, one.getFillType());
- one.dumpHex();
- SkDebugf("two: fill=%d\n", two.getFillType());
- two.dumpHex();
- SkASSERT(0);
- return false;
- }
- SkPath pathOut, scaledPathOut;
- SkRegion rgnA, rgnB, openClip, rgnOut;
- openClip.setRect(-16000, -16000, 16000, 16000);
- rgnA.setPath(one, openClip);
- rgnB.setPath(two, openClip);
- rgnOut.op(rgnA, rgnB, (SkRegion::Op) op);
- rgnOut.getBoundaryPath(&pathOut);
- SkMatrix scale;
- debug_scale_matrix(one, two, scale);
- SkRegion scaledRgnA, scaledRgnB, scaledRgnOut;
- SkPath scaledA, scaledB;
- scaledA.addPath(one, scale);
- scaledA.setFillType(one.getFillType());
- scaledB.addPath(two, scale);
- scaledB.setFillType(two.getFillType());
- scaledRgnA.setPath(scaledA, openClip);
- scaledRgnB.setPath(scaledB, openClip);
- scaledRgnOut.op(scaledRgnA, scaledRgnB, (SkRegion::Op) op);
- scaledRgnOut.getBoundaryPath(&scaledPathOut);
- SkBitmap bitmap;
- SkPath scaledOut;
- scaledOut.addPath(*result, scale);
- scaledOut.setFillType(result->getFillType());
- int errors = debug_paths_draw_the_same(scaledPathOut, scaledOut, bitmap);
- const int MAX_ERRORS = 9;
- if (errors > MAX_ERRORS) {
- SkDebugf("%s did not expect failure\none: fill=%d\n", __FUNCTION__, one.getFillType());
- one.dumpHex();
- SkDebugf("two: fill=%d\n", two.getFillType());
- two.dumpHex();
- SkASSERT(0);
- }
- return true;
-#else
return OpDebug(one, two, op, result SkDEBUGPARAMS(true) SkDEBUGPARAMS(nullptr));
-#endif
}