aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkPathOpsOp.cpp
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@skia.org>2018-06-18 08:53:00 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-06-18 13:30:38 +0000
commit1bb47df4fc8edf62b0463d088214ed1ffb909ca9 (patch)
treeb0feb88d7609d30eef13946af3b2499567b80120 /src/pathops/SkPathOpsOp.cpp
parent63132864e96657ea1a74b93acf5a00d40ebe49b3 (diff)
fast path for pathops
Add faster path for simple but common path ops: - intersect two rects - all ops where one operand is empty R=halcanary@google.com Bug: skia:8049 Change-Id: I2a516d095feae8478ee9433262c9c77e5e18ce81 Reviewed-on: https://skia-review.googlesource.com/132929 Auto-Submit: Cary Clark <caryclark@skia.org> Reviewed-by: Cary Clark <caryclark@skia.org> Commit-Queue: Cary Clark <caryclark@skia.org>
Diffstat (limited to 'src/pathops/SkPathOpsOp.cpp')
-rw-r--r--src/pathops/SkPathOpsOp.cpp53
1 files changed, 45 insertions, 8 deletions
diff --git a/src/pathops/SkPathOpsOp.cpp b/src/pathops/SkPathOpsOp.cpp
index ee2b200f62..4dd687922f 100644
--- a/src/pathops/SkPathOpsOp.cpp
+++ b/src/pathops/SkPathOpsOp.cpp
@@ -217,12 +217,6 @@ extern void (*gVerboseFinalize)();
bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result
SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)) {
- SkSTArenaAlloc<4096> allocator; // FIXME: add a constant expression here, tune
- SkOpContour contour;
- SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
- SkOpGlobalState globalState(contourList, &allocator
- SkDEBUGPARAMS(skipAssert) SkDEBUGPARAMS(testName));
- SkOpCoincidence coincidence(&globalState);
#if DEBUG_DUMP_VERIFY
#ifndef SK_DEBUG
const char* testName = "release";
@@ -232,8 +226,51 @@ bool OpDebug(const SkPath& one, const SkPath& two, SkPathOp op, SkPath* result
}
#endif
op = gOpInverse[op][one.isInverseFillType()][two.isInverseFillType()];
- SkPath::FillType fillType = gOutInverse[op][one.isInverseFillType()][two.isInverseFillType()]
- ? SkPath::kInverseEvenOdd_FillType : SkPath::kEvenOdd_FillType;
+ bool inverseFill = gOutInverse[op][one.isInverseFillType()][two.isInverseFillType()];
+ SkPath::FillType fillType = inverseFill ? SkPath::kInverseEvenOdd_FillType :
+ SkPath::kEvenOdd_FillType;
+ SkRect rect1, rect2;
+ if (kIntersect_SkPathOp == op && one.isRect(&rect1) && two.isRect(&rect2)) {
+ result->reset();
+ result->setFillType(fillType);
+ if (rect1.intersect(rect2)) {
+ result->addRect(rect1);
+ }
+ return true;
+ }
+ if (one.isEmpty() || two.isEmpty()) {
+ SkPath work;
+ switch (op) {
+ case kIntersect_SkPathOp:
+ break;
+ case kUnion_SkPathOp:
+ case kXOR_SkPathOp:
+ work = one.isEmpty() ? two : one;
+ break;
+ case kDifference_SkPathOp:
+ if (!one.isEmpty()) {
+ work = one;
+ }
+ break;
+ case kReverseDifference_SkPathOp:
+ if (!two.isEmpty()) {
+ work = two;
+ }
+ break;
+ default:
+ SkASSERT(0); // unhandled case
+ }
+ if (inverseFill != work.isInverseFillType()) {
+ work.toggleInverseFillType();
+ }
+ return Simplify(work, result);
+ }
+ SkSTArenaAlloc<4096> allocator; // FIXME: add a constant expression here, tune
+ SkOpContour contour;
+ SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
+ SkOpGlobalState globalState(contourList, &allocator
+ SkDEBUGPARAMS(skipAssert) SkDEBUGPARAMS(testName));
+ SkOpCoincidence coincidence(&globalState);
SkScalar scaleFactor = SkTMax(ScaleFactor(one), ScaleFactor(two));
SkPath scaledOne, scaledTwo;
const SkPath* minuend, * subtrahend;