aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils/debugger
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-05-19 13:53:10 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-05-19 13:53:10 +0000
commit2a67e123a3e559774a16a58cbe5106bc0fb86740 (patch)
treeb55bd6606e329ded2b58310f925a78e615bbe1d1 /src/utils/debugger
parent2ee3c2ce6499cb7ce15b59420dd4514ad01d0318 (diff)
This adds a checkbox to the debugger to allow seeing the effect pathops has on the clip. A new tab shows the C code that the pathops generate.
Once in place, this CL found a bug in the pathops code where it was not handling empty clip stack elements correctly. The Cl also has the change to SkCanvas to fix this bug. R=robertphillips@google.com, reed@google.com Author: caryclark@google.com Review URL: https://codereview.chromium.org/282283002 git-svn-id: http://skia.googlecode.com/svn/trunk@14774 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/utils/debugger')
-rw-r--r--src/utils/debugger/SkDebugCanvas.cpp151
-rw-r--r--src/utils/debugger/SkDebugCanvas.h19
2 files changed, 169 insertions, 1 deletions
diff --git a/src/utils/debugger/SkDebugCanvas.cpp b/src/utils/debugger/SkDebugCanvas.cpp
index 14fbf8888a..89a388e110 100644
--- a/src/utils/debugger/SkDebugCanvas.cpp
+++ b/src/utils/debugger/SkDebugCanvas.cpp
@@ -240,12 +240,14 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
SkASSERT(index < fCommandVector.count());
int i = 0;
+ bool pathOpsMode = getAllowSimplifyClip();
+ canvas->setAllowSimplifyClip(pathOpsMode);
// This only works assuming the canvas and device are the same ones that
// were previously drawn into because they need to preserve all saves
// and restores.
// The visibility filter also requires a full re-draw - otherwise we can
// end up drawing the filter repeatedly.
- if (fIndex < index && !fFilter && !fMegaVizMode) {
+ if (fIndex < index && !fFilter && !fMegaVizMode && !pathOpsMode) {
i = fIndex + 1;
} else {
for (int j = 0; j < fOutstandingSaveCount; j++) {
@@ -335,6 +337,28 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index) {
canvas->restore();
}
+ if (pathOpsMode) {
+ this->resetClipStackData();
+ const SkClipStack* clipStack = canvas->getClipStack();
+ SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
+ const SkClipStack::Element* element;
+ SkPath devPath;
+ while ((element = iter.next())) {
+ SkClipStack::Element::Type type = element->getType();
+ SkPath operand;
+ if (type != SkClipStack::Element::kEmpty_Type) {
+ element->asPath(&operand);
+ }
+ SkRegion::Op elementOp = element->getOp();
+ this->addClipStackData(devPath, operand, elementOp);
+ if (elementOp == SkRegion::kReplace_Op) {
+ devPath = operand;
+ } else {
+ Op(devPath, operand, (SkPathOp) elementOp, &devPath);
+ }
+ }
+ this->lastClipStackData(devPath);
+ }
fMatrix = canvas->getTotalMatrix();
if (!canvas->getClipDeviceBounds(&fClip)) {
fClip.setEmpty();
@@ -588,3 +612,128 @@ void SkDebugCanvas::toggleCommand(int index, bool toggle) {
SkASSERT(index < fCommandVector.count());
fCommandVector[index]->setVisible(toggle);
}
+
+static const char* gFillTypeStrs[] = {
+ "kWinding_FillType",
+ "kEvenOdd_FillType",
+ "kInverseWinding_FillType",
+ "kInverseEvenOdd_FillType"
+};
+
+static const char* gOpStrs[] = {
+ "kDifference_PathOp",
+ "kIntersect_PathOp",
+ "kUnion_PathOp",
+ "kXor_PathOp",
+ "kReverseDifference_PathOp",
+};
+
+static const char kHTML4SpaceIndent[] = "&nbsp;&nbsp;&nbsp;&nbsp;";
+
+void SkDebugCanvas::outputScalar(SkScalar num) {
+ if (num == (int) num) {
+ fClipStackData.appendf("%d", (int) num);
+ } else {
+ SkString str;
+ str.printf("%1.9g", num);
+ int width = (int) str.size();
+ const char* cStr = str.c_str();
+ while (cStr[width - 1] == '0') {
+ --width;
+ }
+ str.resize(width);
+ fClipStackData.appendf("%sf", str.c_str());
+ }
+}
+
+void SkDebugCanvas::outputPointsCommon(const SkPoint* pts, int count) {
+ for (int index = 0; index < count; ++index) {
+ this->outputScalar(pts[index].fX);
+ fClipStackData.appendf(", ");
+ this->outputScalar(pts[index].fY);
+ if (index + 1 < count) {
+ fClipStackData.appendf(", ");
+ }
+ }
+}
+
+void SkDebugCanvas::outputPoints(const SkPoint* pts, int count) {
+ this->outputPointsCommon(pts, count);
+ fClipStackData.appendf(");<br>");
+}
+
+void SkDebugCanvas::outputConicPoints(const SkPoint* pts, SkScalar weight) {
+ this->outputPointsCommon(pts, 2);
+ fClipStackData.appendf(", ");
+ this->outputScalar(weight);
+ fClipStackData.appendf(");<br>");
+}
+
+void SkDebugCanvas::addPathData(const SkPath& path, const char* pathName) {
+ SkPath::RawIter iter(path);
+ SkPath::FillType fillType = path.getFillType();
+ fClipStackData.appendf("%sSkPath %s;<br>", kHTML4SpaceIndent, pathName);
+ fClipStackData.appendf("%s%s.setFillType(SkPath::%s);<br>", kHTML4SpaceIndent, pathName,
+ gFillTypeStrs[fillType]);
+ iter.setPath(path);
+ uint8_t verb;
+ SkPoint pts[4];
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ fClipStackData.appendf("%s%s.moveTo(", kHTML4SpaceIndent, pathName);
+ this->outputPoints(&pts[0], 1);
+ continue;
+ case SkPath::kLine_Verb:
+ fClipStackData.appendf("%s%s.lineTo(", kHTML4SpaceIndent, pathName);
+ this->outputPoints(&pts[1], 1);
+ break;
+ case SkPath::kQuad_Verb:
+ fClipStackData.appendf("%s%s.quadTo(", kHTML4SpaceIndent, pathName);
+ this->outputPoints(&pts[1], 2);
+ break;
+ case SkPath::kConic_Verb:
+ fClipStackData.appendf("%s%s.conicTo(", kHTML4SpaceIndent, pathName);
+ this->outputConicPoints(&pts[1], iter.conicWeight());
+ break;
+ case SkPath::kCubic_Verb:
+ fClipStackData.appendf("%s%s.cubicTo(", kHTML4SpaceIndent, pathName);
+ this->outputPoints(&pts[1], 3);
+ break;
+ case SkPath::kClose_Verb:
+ fClipStackData.appendf("%s%s.close();<br>", kHTML4SpaceIndent, pathName);
+ break;
+ default:
+ SkDEBUGFAIL("bad verb");
+ return;
+ }
+ }
+}
+
+void SkDebugCanvas::addClipStackData(const SkPath& devPath, const SkPath& operand,
+ SkRegion::Op elementOp) {
+ if (elementOp == SkRegion::kReplace_Op) {
+ if (!lastClipStackData(devPath)) {
+ fSaveDevPath = operand;
+ }
+ fCalledAddStackData = false;
+ } else {
+ fClipStackData.appendf("<br>static void test(skiatest::Reporter* reporter,"
+ " const char* filename) {<br>");
+ addPathData(fCalledAddStackData ? devPath : fSaveDevPath, "path");
+ addPathData(operand, "pathB");
+ fClipStackData.appendf("%stestPathOp(reporter, path, pathB, %s, filename);<br>",
+ kHTML4SpaceIndent, gOpStrs[elementOp]);
+ fClipStackData.appendf("}<br>");
+ fCalledAddStackData = true;
+ }
+}
+
+bool SkDebugCanvas::lastClipStackData(const SkPath& devPath) {
+ if (fCalledAddStackData) {
+ fClipStackData.appendf("<br>");
+ addPathData(devPath, "pathOut");
+ return true;
+ }
+ return false;
+}
diff --git a/src/utils/debugger/SkDebugCanvas.h b/src/utils/debugger/SkDebugCanvas.h
index d4fded7c1a..be1b8608be 100644
--- a/src/utils/debugger/SkDebugCanvas.h
+++ b/src/utils/debugger/SkDebugCanvas.h
@@ -12,6 +12,7 @@
#include "SkCanvas.h"
#include "SkDrawCommand.h"
+#include "SkPathOps.h"
#include "SkPicture.h"
#include "SkTArray.h"
#include "SkString.h"
@@ -37,6 +38,8 @@ public:
void setOutstandingSaveCount(int saveCount) { fOutstandingSaveCount = saveCount; }
int getOutstandingSaveCount() const { return fOutstandingSaveCount; }
+ bool getAllowSimplifyClip() const { return fAllowSimplifyClip; }
+
void setPicture(SkPicture* picture) { fPicture = picture; }
/**
@@ -151,6 +154,8 @@ public:
fUserMatrix = matrix;
}
+ SkString clipStackData() const { return fClipStackData; }
+
////////////////////////////////////////////////////////////////////////////////
// Inherited from SkCanvas
////////////////////////////////////////////////////////////////////////////////
@@ -266,6 +271,10 @@ private:
SkMatrix fMatrix;
SkIRect fClip;
+ SkString fClipStackData;
+ bool fCalledAddStackData;
+ SkPath fSaveDevPath;
+
bool fOverdrawViz;
SkDrawFilter* fOverdrawFilter;
@@ -311,6 +320,16 @@ private:
return 0;
}
+ void resetClipStackData() { fClipStackData.reset(); fCalledAddStackData = false; }
+
+ void addClipStackData(const SkPath& devPath, const SkPath& operand, SkRegion::Op elementOp);
+ void addPathData(const SkPath& path, const char* pathName);
+ bool lastClipStackData(const SkPath& devPath);
+ void outputConicPoints(const SkPoint* pts, SkScalar weight);
+ void outputPoints(const SkPoint* pts, int count);
+ void outputPointsCommon(const SkPoint* pts, int count);
+ void outputScalar(SkScalar num);
+
typedef SkCanvas INHERITED;
};