remove pathop template

(fixing msan/asan/ubsan failure)

Pathops used templates for curve intersection.
Since only one template is required if curves share
an abstract base, remove the template altogether.

This makes the code easier to read, and incidentally
makes it slightly smaller and much faster.

This also removes debugging code specific to templates,
and removes Simplify code which isn't covered by tests
or fuzz.

This shaves the execution time of
pathops_unittest -V -x from 6m to 3m23s.

R=kjlubick@google.com

Bug: skia:
Change-Id: I3392df98244083d0327ce9c787dfe24d326ef4ed
Reviewed-on: https://skia-review.googlesource.com/c/162742
Commit-Queue: Cary Clark <caryclark@skia.org>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
Cary Clark 2018-10-16 16:06:24 -04:00 committed by Skia Commit-Bot
parent 0b8fcbcfa3
commit 8762fb67bc
17 changed files with 2737 additions and 3390 deletions

View File

@ -269,11 +269,10 @@ public:
int intersectRay(const SkDQuad&, const SkDLine&); int intersectRay(const SkDQuad&, const SkDLine&);
int intersectRay(const SkDConic&, const SkDLine&); int intersectRay(const SkDConic&, const SkDLine&);
int intersectRay(const SkDCubic&, const SkDLine&); int intersectRay(const SkDCubic&, const SkDLine&);
#if PATH_OP_COMPILE_FOR_SIZE
int intersectRay(const SkTCurve& tCurve, const SkDLine& line) { int intersectRay(const SkTCurve& tCurve, const SkDLine& line) {
return tCurve.intersectRay(this, line); return tCurve.intersectRay(this, line);
} }
#endif
void merge(const SkIntersections& , int , const SkIntersections& , int ); void merge(const SkIntersections& , int , const SkIntersections& , int );
int mostOutside(double rangeStart, double rangeEnd, const SkDPoint& origin) const; int mostOutside(double rangeStart, double rangeEnd, const SkDPoint& origin) const;
void removeOne(int index); void removeOne(int index);

View File

@ -985,15 +985,17 @@ bool SkOpSegment::markAngle(int maxWinding, int sumWinding, int oppMaxWinding,
return false; return false;
} }
#if DEBUG_WINDING #if DEBUG_WINDING
SkOpSpanBase* last = *result; if (result) {
if (last) { SkOpSpanBase* last = *result;
SkDebugf("%s last segment=%d span=%d", __FUNCTION__, if (last) {
last->segment()->debugID(), last->debugID()); SkDebugf("%s last segment=%d span=%d", __FUNCTION__,
if (!last->final()) { last->segment()->debugID(), last->debugID());
SkDebugf(" windSum="); if (!last->final()) {
SkPathOpsDebug::WindingPrintf(last->upCast()->windSum()); SkDebugf(" windSum=");
SkPathOpsDebug::WindingPrintf(last->upCast()->windSum());
}
SkDebugf(" \n");
} }
SkDebugf(" \n");
} }
#endif #endif
return true; return true;

View File

@ -173,22 +173,18 @@ SkDPoint SkDConic::subDivide(const SkDPoint& a, const SkDPoint& c, double t1, do
return chopped[1]; return chopped[1];
} }
#if PATH_OP_COMPILE_FOR_SIZE int SkTConic::intersectRay(SkIntersections* i, const SkDLine& line) const {
return i->intersectRay(fConic, line);
}
int SkTConic::intersectRay(SkIntersections* i, const SkDLine& line) const { bool SkTConic::hullIntersects(const SkDQuad& quad, bool* isLinear) const {
return i->intersectRay(fConic, line); return quad.hullIntersects(fConic, isLinear);
} }
bool SkTConic::hullIntersects(const SkDQuad& quad, bool* isLinear) const { bool SkTConic::hullIntersects(const SkDCubic& cubic, bool* isLinear) const {
return quad.hullIntersects(fConic, isLinear); return cubic.hullIntersects(fConic, isLinear);
} }
bool SkTConic::hullIntersects(const SkDCubic& cubic, bool* isLinear) const { void SkTConic::setBounds(SkDRect* rect) const {
return cubic.hullIntersects(fConic, isLinear); rect->setBounds(fConic);
} }
void SkTConic::setBounds(SkDRect* rect) const {
rect->setBounds(fConic);
}
#endif

View File

@ -8,7 +8,6 @@
#ifndef SkPathOpsConic_DEFINED #ifndef SkPathOpsConic_DEFINED
#define SkPathOpsConic_DEFINED #define SkPathOpsConic_DEFINED
#include "SkPathOpsPoint.h"
#include "SkPathOpsQuad.h" #include "SkPathOpsQuad.h"
struct SkDConic { struct SkDConic {
@ -29,6 +28,7 @@ struct SkDConic {
void debugInit() { void debugInit() {
fPts.debugInit(); fPts.debugInit();
fWeight = 0;
} }
void debugSet(const SkDPoint* pts, SkScalar weight); void debugSet(const SkDPoint* pts, SkScalar weight);
@ -133,11 +133,6 @@ struct SkDConic {
}; };
#if PATH_OP_COMPILE_FOR_SIZE
#include "SkArenaAlloc.h"
#include "SkPathOpsTCurve.h"
class SkTConic : public SkTCurve { class SkTConic : public SkTCurve {
public: public:
SkDConic fConic; SkDConic fConic;
@ -156,6 +151,9 @@ public:
bool collapsed() const override { return fConic.collapsed(); } bool collapsed() const override { return fConic.collapsed(); }
bool controlsInside() const override { return fConic.controlsInside(); } bool controlsInside() const override { return fConic.controlsInside(); }
void debugInit() override { return fConic.debugInit(); } void debugInit() override { return fConic.debugInit(); }
#if DEBUG_T_SECT
void dumpID(int id) const override { return fConic.dumpID(id); }
#endif
SkDVector dxdyAtT(double t) const override { return fConic.dxdyAtT(t); } SkDVector dxdyAtT(double t) const override { return fConic.dxdyAtT(t); }
#ifdef SK_DEBUG #ifdef SK_DEBUG
SkOpGlobalState* globalState() const override { return fConic.globalState(); } SkOpGlobalState* globalState() const override { return fConic.globalState(); }
@ -192,5 +190,4 @@ public:
} }
}; };
#endif // PATH_OP_COMPILE_FOR_SIZE
#endif #endif

View File

@ -733,22 +733,18 @@ double SkDCubic::top(const SkDCubic& dCurve, double startT, double endT, SkDPoin
return topT; return topT;
} }
#if PATH_OP_COMPILE_FOR_SIZE int SkTCubic::intersectRay(SkIntersections* i, const SkDLine& line) const {
return i->intersectRay(fCubic, line);
}
int SkTCubic::intersectRay(SkIntersections* i, const SkDLine& line) const { bool SkTCubic::hullIntersects(const SkDQuad& quad, bool* isLinear) const {
return i->intersectRay(fCubic, line); return quad.hullIntersects(fCubic, isLinear);
} }
bool SkTCubic::hullIntersects(const SkDQuad& quad, bool* isLinear) const { bool SkTCubic::hullIntersects(const SkDConic& conic, bool* isLinear) const {
return quad.hullIntersects(fCubic, isLinear); return conic.hullIntersects(fCubic, isLinear);
} }
bool SkTCubic::hullIntersects(const SkDConic& conic, bool* isLinear) const { void SkTCubic::setBounds(SkDRect* rect) const {
return conic.hullIntersects(fCubic, isLinear); rect->setBounds(fCubic);
} }
void SkTCubic::setBounds(SkDRect* rect) const {
rect->setBounds(fCubic);
}
#endif

View File

@ -8,8 +8,9 @@
#ifndef SkPathOpsCubic_DEFINED #ifndef SkPathOpsCubic_DEFINED
#define SkPathOpsCubic_DEFINED #define SkPathOpsCubic_DEFINED
#include "SkArenaAlloc.h"
#include "SkPath.h" #include "SkPath.h"
#include "SkPathOpsPoint.h" #include "SkPathOpsTCurve.h"
struct SkDCubicPair; struct SkDCubicPair;
@ -180,11 +181,6 @@ struct SkDCubicPair {
SkDPoint pts[7]; SkDPoint pts[7];
}; };
#if PATH_OP_COMPILE_FOR_SIZE
#include "SkArenaAlloc.h"
#include "SkPathOpsTCurve.h"
class SkTCubic : public SkTCurve { class SkTCubic : public SkTCurve {
public: public:
SkDCubic fCubic; SkDCubic fCubic;
@ -203,6 +199,9 @@ public:
bool collapsed() const override { return fCubic.collapsed(); } bool collapsed() const override { return fCubic.collapsed(); }
bool controlsInside() const override { return fCubic.controlsInside(); } bool controlsInside() const override { return fCubic.controlsInside(); }
void debugInit() override { return fCubic.debugInit(); } void debugInit() override { return fCubic.debugInit(); }
#if DEBUG_T_SECT
void dumpID(int id) const override { return fCubic.dumpID(id); }
#endif
SkDVector dxdyAtT(double t) const override { return fCubic.dxdyAtT(t); } SkDVector dxdyAtT(double t) const override { return fCubic.dxdyAtT(t); }
#ifdef SK_DEBUG #ifdef SK_DEBUG
SkOpGlobalState* globalState() const override { return fCubic.globalState(); } SkOpGlobalState* globalState() const override { return fCubic.globalState(); }
@ -238,6 +237,4 @@ public:
} }
}; };
#endif // PATH_OP_COMPILE_FOR_SIZE
#endif #endif

View File

@ -29,7 +29,7 @@ struct SkDLine;
struct SkDQuad; struct SkDQuad;
struct SkDConic; struct SkDConic;
struct SkDCubic; struct SkDCubic;
template<typename TCurve, typename OppCurve> class SkTSect; class SkTSect;
// dummy classes to fool msvs Visual Studio 2018 Immediate Window // dummy classes to fool msvs Visual Studio 2018 Immediate Window
#define DummyClasses(a, b) \ #define DummyClasses(a, b) \
@ -114,7 +114,7 @@ DummyClasses(Cubic, Cubic);
#define DEBUG_ASSEMBLE 1 #define DEBUG_ASSEMBLE 1
#define DEBUG_COINCIDENCE 1 #define DEBUG_COINCIDENCE 1
#define DEBUG_COINCIDENCE_DUMP 0 #define DEBUG_COINCIDENCE_DUMP 0
#define DEBUG_COINCIDENCE_ORDER 0 // tight arc quads may generate out-of-order coincdence spans #define DEBUG_COINCIDENCE_ORDER 0 // tight arc quads may generate out-of-order coincidence spans
#define DEBUG_COINCIDENCE_VERBOSE 1 #define DEBUG_COINCIDENCE_VERBOSE 1
#define DEBUG_CUBIC_BINARY_SEARCH 0 #define DEBUG_CUBIC_BINARY_SEARCH 0
#define DEBUG_CUBIC_SPLIT 1 #define DEBUG_CUBIC_SPLIT 1
@ -379,136 +379,107 @@ public:
}; };
// Visual Studio 2017 does not permit calling member functions from the Immediate Window. // Visual Studio 2017 does not permit calling member functions from the Immediate Window.
// Global functions work fine, however. Use globals within a namespace rather than // Global functions work fine, however. Use globals rather than static members inside a class.
// static members inside a class. const SkOpAngle* AngleAngle(const SkOpAngle*, int id);
namespace SkOpDebug { SkOpContour* AngleContour(SkOpAngle*, int id);
const SkOpAngle* AngleAngle(const SkOpAngle*, int id); const SkOpPtT* AnglePtT(const SkOpAngle*, int id);
SkOpContour* AngleContour(SkOpAngle*, int id); const SkOpSegment* AngleSegment(const SkOpAngle*, int id);
const SkOpPtT* AnglePtT(const SkOpAngle*, int id); const SkOpSpanBase* AngleSpan(const SkOpAngle*, int id);
const SkOpSegment* AngleSegment(const SkOpAngle*, int id);
const SkOpSpanBase* AngleSpan(const SkOpAngle*, int id);
const SkOpAngle* ContourAngle(SkOpContour*, int id); const SkOpAngle* ContourAngle(SkOpContour*, int id);
SkOpContour* ContourContour(SkOpContour*, int id); SkOpContour* ContourContour(SkOpContour*, int id);
const SkOpPtT* ContourPtT(SkOpContour*, int id); const SkOpPtT* ContourPtT(SkOpContour*, int id);
const SkOpSegment* ContourSegment(SkOpContour*, int id); const SkOpSegment* ContourSegment(SkOpContour*, int id);
const SkOpSpanBase* ContourSpan(SkOpContour*, int id); const SkOpSpanBase* ContourSpan(SkOpContour*, int id);
const SkOpAngle* CoincidenceAngle(SkOpCoincidence*, int id); const SkOpAngle* CoincidenceAngle(SkOpCoincidence*, int id);
SkOpContour* CoincidenceContour(SkOpCoincidence*, int id); SkOpContour* CoincidenceContour(SkOpCoincidence*, int id);
const SkOpPtT* CoincidencePtT(SkOpCoincidence*, int id); const SkOpPtT* CoincidencePtT(SkOpCoincidence*, int id);
const SkOpSegment* CoincidenceSegment(SkOpCoincidence*, int id); const SkOpSegment* CoincidenceSegment(SkOpCoincidence*, int id);
const SkOpSpanBase* CoincidenceSpan(SkOpCoincidence*, int id); const SkOpSpanBase* CoincidenceSpan(SkOpCoincidence*, int id);
const SkOpAngle* PtTAngle(const SkOpPtT*, int id); const SkOpAngle* PtTAngle(const SkOpPtT*, int id);
SkOpContour* PtTContour(SkOpPtT*, int id); SkOpContour* PtTContour(SkOpPtT*, int id);
const SkOpPtT* PtTPtT(const SkOpPtT*, int id); const SkOpPtT* PtTPtT(const SkOpPtT*, int id);
const SkOpSegment* PtTSegment(const SkOpPtT*, int id); const SkOpSegment* PtTSegment(const SkOpPtT*, int id);
const SkOpSpanBase* PtTSpan(const SkOpPtT*, int id); const SkOpSpanBase* PtTSpan(const SkOpPtT*, int id);
const SkOpAngle* SegmentAngle(const SkOpSegment*, int id); const SkOpAngle* SegmentAngle(const SkOpSegment*, int id);
SkOpContour* SegmentContour(SkOpSegment*, int id); SkOpContour* SegmentContour(SkOpSegment*, int id);
const SkOpPtT* SegmentPtT(const SkOpSegment*, int id); const SkOpPtT* SegmentPtT(const SkOpSegment*, int id);
const SkOpSegment* SegmentSegment(const SkOpSegment*, int id); const SkOpSegment* SegmentSegment(const SkOpSegment*, int id);
const SkOpSpanBase* SegmentSpan(const SkOpSegment*, int id); const SkOpSpanBase* SegmentSpan(const SkOpSegment*, int id);
const SkOpAngle* SpanAngle(const SkOpSpanBase*, int id); const SkOpAngle* SpanAngle(const SkOpSpanBase*, int id);
SkOpContour* SpanContour(SkOpSpanBase*, int id); SkOpContour* SpanContour(SkOpSpanBase*, int id);
const SkOpPtT* SpanPtT(const SkOpSpanBase*, int id); const SkOpPtT* SpanPtT(const SkOpSpanBase*, int id);
const SkOpSegment* SpanSegment(const SkOpSpanBase*, int id); const SkOpSegment* SpanSegment(const SkOpSpanBase*, int id);
const SkOpSpanBase* SpanSpan(const SkOpSpanBase*, int id); const SkOpSpanBase* SpanSpan(const SkOpSpanBase*, int id);
#if DEBUG_DUMP_VERIFY #if DEBUG_DUMP_VERIFY
void DumpOp(const SkPath& one, const SkPath& two, SkPathOp op, void DumpOp(const SkPath& one, const SkPath& two, SkPathOp op,
const char* testName); const char* testName);
void DumpOp(FILE* file, const SkPath& one, const SkPath& two, SkPathOp op, void DumpOp(FILE* file, const SkPath& one, const SkPath& two, SkPathOp op,
const char* testName); const char* testName);
void DumpSimplify(const SkPath& path, const char* testName); void DumpSimplify(const SkPath& path, const char* testName);
void DumpSimplify(FILE* file, const SkPath& path, const char* testName); void DumpSimplify(FILE* file, const SkPath& path, const char* testName);
void ReportOpFail(const SkPath& one, const SkPath& two, SkPathOp op); void ReportOpFail(const SkPath& one, const SkPath& two, SkPathOp op);
void ReportSimplifyFail(const SkPath& path); void ReportSimplifyFail(const SkPath& path);
void VerifyOp(const SkPath& one, const SkPath& two, SkPathOp op, void VerifyOp(const SkPath& one, const SkPath& two, SkPathOp op,
const SkPath& result); const SkPath& result);
void VerifySimplify(const SkPath& path, const SkPath& result); void VerifySimplify(const SkPath& path, const SkPath& result);
#endif #endif
// global path dumps for msvs Visual Studio 17 to use from Immediate Window // global path dumps for msvs Visual Studio 17 to use from Immediate Window
void Dump(const SkOpContour& ); void Dump(const SkOpContour& );
void DumpAll(const SkOpContour& ); void DumpAll(const SkOpContour& );
void DumpAngles(const SkOpContour& ); void DumpAngles(const SkOpContour& );
void DumpContours(const SkOpContour& ); void DumpContours(const SkOpContour& );
void DumpContoursAll(const SkOpContour& ); void DumpContoursAll(const SkOpContour& );
void DumpContoursAngles(const SkOpContour& ); void DumpContoursAngles(const SkOpContour& );
void DumpContoursPts(const SkOpContour& ); void DumpContoursPts(const SkOpContour& );
void DumpContoursPt(const SkOpContour& , int segmentID); void DumpContoursPt(const SkOpContour& , int segmentID);
void DumpContoursSegment(const SkOpContour& , int segmentID); void DumpContoursSegment(const SkOpContour& , int segmentID);
void DumpContoursSpan(const SkOpContour& , int segmentID); void DumpContoursSpan(const SkOpContour& , int segmentID);
void DumpContoursSpans(const SkOpContour& ); void DumpContoursSpans(const SkOpContour& );
void DumpPt(const SkOpContour& , int ); void DumpPt(const SkOpContour& , int );
void DumpPts(const SkOpContour& , const char* prefix = "seg"); void DumpPts(const SkOpContour& , const char* prefix = "seg");
void DumpSegment(const SkOpContour& , int ); void DumpSegment(const SkOpContour& , int );
void DumpSegments(const SkOpContour& , const char* prefix = "seg", SkPathOp op = (SkPathOp) -1); void DumpSegments(const SkOpContour& , const char* prefix = "seg", SkPathOp op = (SkPathOp) -1);
void DumpSpan(const SkOpContour& , int ); void DumpSpan(const SkOpContour& , int );
void DumpSpans(const SkOpContour& ); void DumpSpans(const SkOpContour& );
void Dump(const SkOpSegment& ); void Dump(const SkOpSegment& );
void DumpAll(const SkOpSegment& ); void DumpAll(const SkOpSegment& );
void DumpAngles(const SkOpSegment& ); void DumpAngles(const SkOpSegment& );
void DumpCoin(const SkOpSegment& ); void DumpCoin(const SkOpSegment& );
void DumpPts(const SkOpSegment& , const char* prefix = "seg"); void DumpPts(const SkOpSegment& , const char* prefix = "seg");
void Dump(const SkOpPtT& ); void Dump(const SkOpPtT& );
void DumpAll(const SkOpPtT& ); void DumpAll(const SkOpPtT& );
void Dump(const SkOpSpanBase& ); void Dump(const SkOpSpanBase& );
void DumpCoin(const SkOpSpanBase& ); void DumpCoin(const SkOpSpanBase& );
void DumpAll(const SkOpSpanBase& ); void DumpAll(const SkOpSpanBase& );
void DumpCoin(const SkOpSpan& ); void DumpCoin(const SkOpSpan& );
bool DumpSpan(const SkOpSpan& ); bool DumpSpan(const SkOpSpan& );
void Dump(const SkDConic& ); void Dump(const SkDConic& );
void DumpID(const SkDConic& , int id); void DumpID(const SkDConic& , int id);
void Dump(const SkDCubic& ); void Dump(const SkDCubic& );
void DumpID(const SkDCubic& , int id); void DumpID(const SkDCubic& , int id);
void Dump(const SkDLine& ); void Dump(const SkDLine& );
void DumpID(const SkDLine& , int id); void DumpID(const SkDLine& , int id);
void Dump(const SkDQuad& ); void Dump(const SkDQuad& );
void DumpID(const SkDQuad& , int id); void DumpID(const SkDQuad& , int id);
void Dump(const SkDPoint& ); void Dump(const SkDPoint& );
void Dump(const SkOpAngle& ); void Dump(const SkOpAngle& );
// dummy declarations to fool msvs Visual Studio 2018 Immediate Window
#define DummyDeclarations(a, b) \
void Dump(const SkDebugTCoincident##a##b& ); \
\
void Dump(const SkDebugTSect##a##b& ); \
void DumpBoth(const SkDebugTSect##a##b& , SkDebugTSect##a##b* ); \
void DumpBounded(const SkDebugTSect##a##b& , int id); \
void DumpBounds(const SkDebugTSect##a##b& ); \
void DumpCoin(const SkDebugTSect##a##b& ); \
void DumpCoinCurves(const SkDebugTSect##a##b& ); \
void DumpCurves(const SkDebugTSect##a##b& ); \
\
void Dump(const SkDebugTSpan##a##b& ); \
void DumpAll(const SkDebugTSpan##a##b& ); \
void DumpBounded(const SkDebugTSpan##a##b& , int id); \
void DumpBounds(const SkDebugTSpan##a##b& ); \
void DumpCoin(const SkDebugTSpan##a##b& )
DummyDeclarations(Quad, Quad);
DummyDeclarations(Conic, Quad);
DummyDeclarations(Conic, Conic);
DummyDeclarations(Cubic, Quad);
DummyDeclarations(Cubic, Conic);
DummyDeclarations(Cubic, Cubic);
#undef DummyDeclarations
}
// generates tools/path_sorter.htm and path_visualizer.htm compatible data // generates tools/path_sorter.htm and path_visualizer.htm compatible data
void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo); void DumpQ(const SkDQuad& quad1, const SkDQuad& quad2, int testNo);

View File

@ -399,22 +399,18 @@ void SkDQuad::SetABC(const double* quad, double* a, double* b, double* c) {
*b -= *c; // b = 2*B - 2*C *b -= *c; // b = 2*B - 2*C
} }
#if PATH_OP_COMPILE_FOR_SIZE int SkTQuad::intersectRay(SkIntersections* i, const SkDLine& line) const {
return i->intersectRay(fQuad, line);
}
int SkTQuad::intersectRay(SkIntersections* i, const SkDLine& line) const { bool SkTQuad::hullIntersects(const SkDConic& conic, bool* isLinear) const {
return i->intersectRay(fQuad, line); return conic.hullIntersects(fQuad, isLinear);
} }
bool SkTQuad::hullIntersects(const SkDConic& conic, bool* isLinear) const { bool SkTQuad::hullIntersects(const SkDCubic& cubic, bool* isLinear) const {
return conic.hullIntersects(fQuad, isLinear); return cubic.hullIntersects(fQuad, isLinear);
} }
bool SkTQuad::hullIntersects(const SkDCubic& cubic, bool* isLinear) const { void SkTQuad::setBounds(SkDRect* rect) const {
return cubic.hullIntersects(fQuad, isLinear); rect->setBounds(fQuad);
} }
void SkTQuad::setBounds(SkDRect* rect) const {
rect->setBounds(fQuad);
}
#endif

View File

@ -8,7 +8,8 @@
#ifndef SkPathOpsQuad_DEFINED #ifndef SkPathOpsQuad_DEFINED
#define SkPathOpsQuad_DEFINED #define SkPathOpsQuad_DEFINED
#include "SkPathOpsPoint.h" #include "SkArenaAlloc.h"
#include "SkPathOpsTCurve.h"
struct SkOpCurve; struct SkOpCurve;
@ -122,10 +123,6 @@ struct SkDQuad {
SkDEBUGCODE(SkOpGlobalState* fDebugGlobalState); SkDEBUGCODE(SkOpGlobalState* fDebugGlobalState);
}; };
#if PATH_OP_COMPILE_FOR_SIZE
#include "SkArenaAlloc.h"
#include "SkPathOpsTCurve.h"
class SkTQuad : public SkTCurve { class SkTQuad : public SkTCurve {
public: public:
@ -145,6 +142,9 @@ public:
bool collapsed() const override { return fQuad.collapsed(); } bool collapsed() const override { return fQuad.collapsed(); }
bool controlsInside() const override { return fQuad.controlsInside(); } bool controlsInside() const override { return fQuad.controlsInside(); }
void debugInit() override { return fQuad.debugInit(); } void debugInit() override { return fQuad.debugInit(); }
#if DEBUG_T_SECT
void dumpID(int id) const override { return fQuad.dumpID(id); }
#endif
SkDVector dxdyAtT(double t) const override { return fQuad.dxdyAtT(t); } SkDVector dxdyAtT(double t) const override { return fQuad.dxdyAtT(t); }
#ifdef SK_DEBUG #ifdef SK_DEBUG
SkOpGlobalState* globalState() const override { return fQuad.globalState(); } SkOpGlobalState* globalState() const override { return fQuad.globalState(); }
@ -181,6 +181,4 @@ public:
} }
}; };
#endif // PATH_OP_COMPILE_FOR_SIZE
#endif #endif

View File

@ -61,10 +61,6 @@ void SkDRect::setBounds(const SkDCubic& curve, const SkDCubic& sub, double start
} }
} }
#if PATH_OP_COMPILE_FOR_SIZE void SkDRect::setBounds(const SkTCurve& curve) {
curve.setBounds(this);
void SkDRect::setBounds(const SkTCurve& curve) { }
curve.setBounds(this);
}
#endif

View File

@ -50,18 +50,14 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* writer) {
if (current->activeWinding(start, end) && !writer->isClosed()) { if (current->activeWinding(start, end) && !writer->isClosed()) {
SkOpSpan* spanStart = start->starter(end); SkOpSpan* spanStart = start->starter(end);
if (!spanStart->done()) { if (!spanStart->done()) {
if (!current->addCurveTo(start, end, writer)) { SkAssertResult(current->addCurveTo(start, end, writer));
return false;
}
current->markDone(spanStart); current->markDone(spanStart);
} }
} }
writer->finishContour(); writer->finishContour();
} else { } else {
SkOpSpanBase* last; SkOpSpanBase* last;
if (!current->markAndChaseDone(start, end, &last)) { SkAssertResult(current->markAndChaseDone(start, end, &last));
return false;
}
if (last && !last->chased()) { if (last && !last->chased()) {
last->setChased(true); last->setChased(true);
SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last)); SkASSERT(!SkPathOpsDebug::ChaseContains(chase, last));
@ -124,15 +120,12 @@ static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* writer) {
start = nextStart; start = nextStart;
end = nextEnd; end = nextEnd;
} while (!writer->isClosed() && (!unsortable || !start->starter(end)->done())); } while (!writer->isClosed() && (!unsortable || !start->starter(end)->done()));
#ifdef SK_DEBUG
if (!writer->isClosed()) { if (!writer->isClosed()) {
SkOpSpan* spanStart = start->starter(end); SkOpSpan* spanStart = start->starter(end);
if (!spanStart->done()) { SkASSERT(spanStart->done());
if (!current->addCurveTo(start, end, writer)) {
return false;
}
current->markDone(spanStart);
}
} }
#endif
writer->finishContour(); writer->finishContour();
SkPathOpsDebug::ShowActiveSpans(contourList); SkPathOpsDebug::ShowActiveSpans(contourList);
} while (true); } while (true);

View File

@ -22,6 +22,9 @@ public:
virtual bool collapsed() const = 0; virtual bool collapsed() const = 0;
virtual bool controlsInside() const = 0; virtual bool controlsInside() const = 0;
virtual void debugInit() = 0; virtual void debugInit() = 0;
#if DEBUG_T_SECT
virtual void dumpID(int id) const = 0;
#endif
virtual SkDVector dxdyAtT(double t) const = 0; virtual SkDVector dxdyAtT(double t) const = 0;
virtual bool hullIntersects(const SkDQuad& , bool* isLinear) const = 0; virtual bool hullIntersects(const SkDQuad& , bool* isLinear) const = 0;
virtual bool hullIntersects(const SkDConic& , bool* isLinear) const = 0; virtual bool hullIntersects(const SkDConic& , bool* isLinear) const = 0;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,6 @@
#include "SkSafe_math.h" // for fabs, sqrt #include "SkSafe_math.h" // for fabs, sqrt
#include "SkScalar.h" #include "SkScalar.h"
#define PATH_OP_COMPILE_FOR_SIZE 1
enum SkPathOpsMask { enum SkPathOpsMask {
kWinding_PathOpsMask = -1, kWinding_PathOpsMask = -1,
kNo_PathOpsMask = 0, kNo_PathOpsMask = 0,

File diff suppressed because it is too large Load Diff

View File

@ -9,216 +9,5 @@
#include "SkPathOpsTSect.h" #include "SkPathOpsTSect.h"
template<typename TCurve, typename OppCurve>
char SkTCoincident<TCurve, OppCurve>::dumpIsCoincidentStr() const {
if (!!fMatch != fMatch) {
return '?';
}
return fMatch ? '*' : 0;
}
template<typename TCurve, typename OppCurve>
void SkTCoincident<TCurve, OppCurve>::dump() const {
SkDebugf("t=%1.9g pt=(%1.9g,%1.9g)%s\n", fPerpT, fPerpPt.fX, fPerpPt.fY,
fMatch ? " match" : "");
}
template<typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::debugSpan(int id) const {
const SkTSpan<TCurve, OppCurve>* test = fHead;
do {
if (test->debugID() == id) {
return test;
}
} while ((test = test->next()));
return nullptr;
}
template<typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* SkTSect<TCurve, OppCurve>::debugT(double t) const {
const SkTSpan<TCurve, OppCurve>* test = fHead;
const SkTSpan<TCurve, OppCurve>* closest = nullptr;
double bestDist = DBL_MAX;
do {
if (between(test->fStartT, t, test->fEndT)) {
return test;
}
double testDist = SkTMin(fabs(test->fStartT - t), fabs(test->fEndT - t));
if (bestDist > testDist) {
bestDist = testDist;
closest = test;
}
} while ((test = test->next()));
SkASSERT(closest);
return closest;
}
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dump() const {
dumpCommon(fHead);
}
extern int gDumpTSectNum;
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpBoth(SkTSect<OppCurve, TCurve>* opp) const {
#if DEBUG_T_SECT_DUMP <= 2
#if DEBUG_T_SECT_DUMP == 2
SkDebugf("%d ", ++gDumpTSectNum);
#endif
this->dump();
SkDebugf("\n");
opp->dump();
SkDebugf("\n");
#elif DEBUG_T_SECT_DUMP == 3
SkDebugf("<div id=\"sect%d\">\n", ++gDumpTSectNum);
if (this->fHead) {
this->dumpCurves();
}
if (opp->fHead) {
opp->dumpCurves();
}
SkDebugf("</div>\n\n");
#endif
}
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpBounded(int id) const {
const SkTSpan<TCurve, OppCurve>* bounded = debugSpan(id);
if (!bounded) {
SkDebugf("no span matches %d\n", id);
return;
}
const SkTSpan<OppCurve, TCurve>* test = bounded->debugOpp()->fHead;
do {
if (test->findOppSpan(bounded)) {
test->dump();
SkDebugf(" ");
}
} while ((test = test->next()));
SkDebugf("\n");
}
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpBounds() const {
const SkTSpan<TCurve, OppCurve>* test = fHead;
do {
test->dumpBounds();
} while ((test = test->next()));
}
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCoin() const {
dumpCommon(fCoincident);
}
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCoinCurves() const {
dumpCommonCurves(fCoincident);
}
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCommon(const SkTSpan<TCurve, OppCurve>* test) const {
SkDebugf("id=%d", debugID());
if (!test) {
SkDebugf(" (empty)");
return;
}
do {
SkDebugf(" ");
test->dump();
} while ((test = test->next()));
}
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCommonCurves(const SkTSpan<TCurve, OppCurve>* test) const {
do {
test->fPart.dumpID(test->debugID());
} while ((test = test->next()));
}
template<typename TCurve, typename OppCurve>
void SkTSect<TCurve, OppCurve>::dumpCurves() const {
dumpCommonCurves(fHead);
}
template<typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugSpan(int id) const {
return SkDEBUGRELEASE(fDebugSect->debugSpan(id), nullptr);
}
template<typename TCurve, typename OppCurve>
const SkTSpan<TCurve, OppCurve>* SkTSpan<TCurve, OppCurve>::debugT(double t) const {
return SkDEBUGRELEASE(fDebugSect->debugT(t), nullptr);
}
template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpAll() const {
dumpID();
SkDebugf("=(%g,%g) [", fStartT, fEndT);
const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded;
while (testBounded) {
const SkTSpan<OppCurve, TCurve>* span = testBounded->fBounded;
const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext;
span->dumpID();
SkDebugf("=(%g,%g)", span->fStartT, span->fEndT);
if (next) {
SkDebugf(" ");
}
testBounded = next;
}
SkDebugf("]\n");
}
template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dump() const {
dumpID();
SkDebugf("=(%g,%g) [", fStartT, fEndT);
const SkTSpanBounded<OppCurve, TCurve>* testBounded = fBounded;
while (testBounded) {
const SkTSpan<OppCurve, TCurve>* span = testBounded->fBounded;
const SkTSpanBounded<OppCurve, TCurve>* next = testBounded->fNext;
span->dumpID();
if (next) {
SkDebugf(",");
}
testBounded = next;
}
SkDebugf("]");
}
template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpBounded(int id) const {
SkDEBUGCODE(fDebugSect->dumpBounded(id));
}
template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpBounds() const {
dumpID();
SkDebugf(" bounds=(%1.9g,%1.9g, %1.9g,%1.9g) boundsMax=%1.9g%s\n",
fBounds.fLeft, fBounds.fTop, fBounds.fRight, fBounds.fBottom, fBoundsMax,
fCollapsed ? " collapsed" : "");
}
template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpCoin() const {
dumpID();
SkDebugf(" coinStart ");
fCoinStart.dump();
SkDebugf(" coinEnd ");
fCoinEnd.dump();
}
template<typename TCurve, typename OppCurve>
void SkTSpan<TCurve, OppCurve>::dumpID() const {
char cS = fCoinStart.dumpIsCoincidentStr();
if (cS) {
SkDebugf("%c", cS);
}
SkDebugf("%d", debugID());
char cE = fCoinEnd.dumpIsCoincidentStr();
if (cE) {
SkDebugf("%c", cE);
}
}
#endif // PathOpsTSectDebug_DEFINED #endif // PathOpsTSectDebug_DEFINED