Revert "SkPathView for ownerless (can live on stack) SkPaths"

This reverts commit 375721d7bb.
Some manual edits needed due to time elapsed.

Bug: chromium:1141332, skia:10566
Change-Id: Iadb15d3f5334d9eed4e7053e9c19d75a0bbeb9de
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/330196
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
This commit is contained in:
Mike Klein 2020-10-28 09:07:09 -05:00 committed by Skia Commit-Bot
parent ca107f3287
commit 71f1266664
23 changed files with 99 additions and 279 deletions

View File

@ -18,7 +18,6 @@
class SkAutoPathBoundsUpdate; class SkAutoPathBoundsUpdate;
class SkData; class SkData;
class SkRRect; class SkRRect;
struct SkPathView;
class SkWStream; class SkWStream;
// WIP -- define this locally, and fix call-sites to use SkPathBuilder (skbug.com/9000) // WIP -- define this locally, and fix call-sites to use SkPathBuilder (skbug.com/9000)
@ -1540,8 +1539,6 @@ public:
Verb autoClose(SkPoint pts[2]); Verb autoClose(SkPoint pts[2]);
}; };
SkPathView view() const;
private: private:
/** \class SkPath::RangeIter /** \class SkPath::RangeIter
Iterates through a raw range of path verbs, points, and conics. All values are returned Iterates through a raw range of path verbs, points, and conics. All values are returned

View File

@ -9,7 +9,6 @@
#define SkPathRef_DEFINED #define SkPathRef_DEFINED
#include "include/core/SkMatrix.h" #include "include/core/SkMatrix.h"
#include "include/core/SkPathTypes.h"
#include "include/core/SkPoint.h" #include "include/core/SkPoint.h"
#include "include/core/SkRRect.h" #include "include/core/SkRRect.h"
#include "include/core/SkRect.h" #include "include/core/SkRect.h"
@ -24,7 +23,6 @@
#include <limits> #include <limits>
#include <tuple> #include <tuple>
struct SkPathView;
class SkRBuffer; class SkRBuffer;
class SkWBuffer; class SkWBuffer;
@ -352,8 +350,6 @@ public:
bool isValid() const; bool isValid() const;
SkDEBUGCODE(void validate() const { SkASSERT(this->isValid()); } ) SkDEBUGCODE(void validate() const { SkASSERT(this->isValid()); } )
SkPathView view(SkPathFillType, SkPathConvexity) const;
private: private:
enum SerializationOffsets { enum SerializationOffsets {
kLegacyRRectOrOvalStartIdx_SerializationShift = 28, // requires 3 bits, ignored. kLegacyRRectOrOvalStartIdx_SerializationShift = 28, // requires 3 bits, ignored.

View File

@ -227,7 +227,7 @@ static SkPath clip(const SkPath& path, SkPoint p0, SkPoint p1) {
SkPoint fPrev = {0, 0}; SkPoint fPrev = {0, 0};
} rec; } rec;
SkEdgeClipper::ClipPath(rotated.view(), clip, false, SkEdgeClipper::ClipPath(rotated, clip, false,
[](SkEdgeClipper* clipper, bool newCtr, void* ctx) { [](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
Rec* rec = (Rec*)ctx; Rec* rec = (Rec*)ctx;

View File

@ -1334,12 +1334,11 @@ bool SkAAClip::setPath(const SkPath& path, const SkRegion* clip, bool doAA) {
Builder builder(ibounds); Builder builder(ibounds);
BuilderBlitter blitter(&builder); BuilderBlitter blitter(&builder);
const SkPathView view = path.view();
if (doAA) { if (doAA) {
SkScan::AntiFillPath(view, snugClip, &blitter, true); SkScan::AntiFillPath(path, snugClip, &blitter, true);
} else { } else {
SkScan::FillPath(view, snugClip, &blitter); SkScan::FillPath(path, snugClip, &blitter);
} }
blitter.finish(); blitter.finish();

View File

@ -834,7 +834,7 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
} }
} }
void (*proc)(const SkPathView&, const SkRasterClip&, SkBlitter*); void (*proc)(const SkPath&, const SkRasterClip&, SkBlitter*);
if (doFill) { if (doFill) {
if (paint.isAntiAlias()) { if (paint.isAntiAlias()) {
proc = SkScan::AntiFillPath; proc = SkScan::AntiFillPath;
@ -875,7 +875,7 @@ void SkDraw::drawDevPath(const SkPath& devPath, const SkPaint& paint, bool drawC
} }
} }
proc(devPath.view(), *fRC, blitter); proc(devPath, *fRC, blitter);
} }
void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint, void SkDraw::drawPath(const SkPath& origSrcPath, const SkPaint& origPaint,

View File

@ -22,7 +22,7 @@
#include "src/core/SkScan.h" #include "src/core/SkScan.h"
static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc, static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc,
const SkRect& r, SkBlitter* blitter) { const SkRect& r, SkBlitter* blitter, SkPath* scratchPath) {
if (ctm.rectStaysRect()) { if (ctm.rectStaysRect()) {
SkRect dr; SkRect dr;
ctm.mapRect(&dr, r); ctm.mapRect(&dr, r);
@ -32,10 +32,9 @@ static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc,
r.toQuad(pts); r.toQuad(pts);
ctm.mapPoints(pts, pts, 4); ctm.mapPoints(pts, pts, 4);
SkRect bounds; scratchPath->rewind();
bounds.setBounds(pts, 4); scratchPath->addPoly(pts, 4, true);
SkScan::FillPath(*scratchPath, rc, blitter);
SkScan::FillPath(SkPathView_quad(pts, bounds), rc, blitter);
} }
} }
@ -104,6 +103,8 @@ void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRe
if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, &alloc, if (auto blitter = SkCreateRasterPipelineBlitter(fDst, p, pipeline, isOpaque, &alloc,
fRC->clipShader())) { fRC->clipShader())) {
SkPath scratchPath;
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
if (colors) { if (colors) {
SkColor4f c4 = SkColor4f::FromColor(colors[i]); SkColor4f c4 = SkColor4f::FromColor(colors[i]);
@ -117,7 +118,7 @@ void SkDraw::drawAtlas(const SkImage* atlas, const SkRSXform xform[], const SkRe
mx.postConcat(fMatrixProvider->localToDevice()); mx.postConcat(fMatrixProvider->localToDevice());
if (updator->update(mx, nullptr)) { if (updator->update(mx, nullptr)) {
fill_rect(mx, *fRC, textures[i], blitter); fill_rect(mx, *fRC, textures[i], blitter, &scratchPath);
} }
} }
} }

View File

@ -14,7 +14,6 @@
#include "src/core/SkGeometry.h" #include "src/core/SkGeometry.h"
#include "src/core/SkLineClipper.h" #include "src/core/SkLineClipper.h"
#include "src/core/SkPathPriv.h" #include "src/core/SkPathPriv.h"
#include "src/core/SkPathView.h"
#include "src/core/SkSafeMath.h" #include "src/core/SkSafeMath.h"
SkEdgeBuilder::Combine SkBasicEdgeBuilder::combineVertical(const SkEdge* edge, SkEdge* last) { SkEdgeBuilder::Combine SkBasicEdgeBuilder::combineVertical(const SkEdge* edge, SkEdge* last) {
@ -219,8 +218,8 @@ char* SkAnalyticEdgeBuilder::allocEdges(size_t n, size_t* size) {
} }
// TODO: maybe get rid of buildPoly() entirely? // TODO: maybe get rid of buildPoly() entirely?
int SkEdgeBuilder::buildPoly(const SkPathView& path, const SkIRect* iclip, bool canCullToTheRight) { int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, bool canCullToTheRight) {
size_t maxEdgeCount = path.fPoints.size(); size_t maxEdgeCount = path.countPoints();
if (iclip) { if (iclip) {
// clipping can turn 1 line into (up to) kMaxClippedLineSegments, since // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since
// we turn portions that are clipped out on the left/right into vertical // we turn portions that are clipped out on the left/right into vertical
@ -287,7 +286,7 @@ int SkEdgeBuilder::buildPoly(const SkPathView& path, const SkIRect* iclip, bool
return SkToInt(edgePtr - (char**)fEdgeList); return SkToInt(edgePtr - (char**)fEdgeList);
} }
int SkEdgeBuilder::build(const SkPathView& path, const SkIRect* iclip, bool canCullToTheRight) { int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, bool canCullToTheRight) {
SkAutoConicToQuads quadder; SkAutoConicToQuads quadder;
const SkScalar conicTol = SK_Scalar1 / 4; const SkScalar conicTol = SK_Scalar1 / 4;
bool is_finite = true; bool is_finite = true;
@ -361,14 +360,14 @@ int SkEdgeBuilder::build(const SkPathView& path, const SkIRect* iclip, bool canC
return is_finite ? fList.count() : 0; return is_finite ? fList.count() : 0;
} }
int SkEdgeBuilder::buildEdges(const SkPathView& path, int SkEdgeBuilder::buildEdges(const SkPath& path,
const SkIRect* shiftedClip) { const SkIRect* shiftedClip) {
// If we're convex, then we need both edges, even if the right edge is past the clip. // If we're convex, then we need both edges, even if the right edge is past the clip.
const bool canCullToTheRight = !path.isConvex(); const bool canCullToTheRight = !path.isConvex();
// We can use our buildPoly() optimization if all the segments are lines. // We can use our buildPoly() optimization if all the segments are lines.
// (Edges are homogeneous and stored contiguously in memory, no need for indirection.) // (Edges are homogeneous and stored contiguously in memory, no need for indirection.)
const int count = SkPath::kLine_SegmentMask == path.fSegmentMask const int count = SkPath::kLine_SegmentMask == path.getSegmentMasks()
? this->buildPoly(path, shiftedClip, canCullToTheRight) ? this->buildPoly(path, shiftedClip, canCullToTheRight)
: this->build (path, shiftedClip, canCullToTheRight); : this->build (path, shiftedClip, canCullToTheRight);

View File

@ -13,11 +13,12 @@
#include "src/core/SkArenaAlloc.h" #include "src/core/SkArenaAlloc.h"
#include "src/core/SkEdge.h" #include "src/core/SkEdge.h"
struct SkPathView; class SkPath;
class SkEdgeBuilder { class SkEdgeBuilder {
public: public:
int buildEdges(const SkPathView&, const SkIRect* shiftedClip); int buildEdges(const SkPath& path,
const SkIRect* shiftedClip);
protected: protected:
SkEdgeBuilder() = default; SkEdgeBuilder() = default;
@ -36,8 +37,8 @@ protected:
}; };
private: private:
int build (const SkPathView&, const SkIRect* clip, bool clipToTheRight); int build (const SkPath& path, const SkIRect* clip, bool clipToTheRight);
int buildPoly(const SkPathView&, const SkIRect* clip, bool clipToTheRight); int buildPoly(const SkPath& path, const SkIRect* clip, bool clipToTheRight);
virtual char* allocEdges(size_t n, size_t* sizeof_edge) = 0; virtual char* allocEdges(size_t n, size_t* sizeof_edge) = 0;
virtual SkRect recoverClip(const SkIRect&) const = 0; virtual SkRect recoverClip(const SkIRect&) const = 0;

View File

@ -560,13 +560,14 @@ void sk_assert_monotonic_x(const SkPoint pts[], int count) {
#include "src/core/SkPathPriv.h" #include "src/core/SkPathPriv.h"
void SkEdgeClipper::ClipPath(const SkPathView& view, const SkRect& clip, bool canCullToTheRight, void SkEdgeClipper::ClipPath(const SkPath& path, const SkRect& clip, bool canCullToTheRight,
void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx) { void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx) {
SkASSERT(view.isFinite()); SkASSERT(path.isFinite());
SkAutoConicToQuads quadder; SkAutoConicToQuads quadder;
const SkScalar conicTol = SK_Scalar1 / 4; const SkScalar conicTol = SK_Scalar1 / 4;
SkPathEdgeIter iter(view); SkPathEdgeIter iter(path);
SkEdgeClipper clipper(canCullToTheRight); SkEdgeClipper clipper(canCullToTheRight);
while (auto e = iter.next()) { while (auto e = iter.next()) {

View File

@ -10,7 +10,6 @@
#define SkEdgeClipper_DEFINED #define SkEdgeClipper_DEFINED
#include "include/core/SkPath.h" #include "include/core/SkPath.h"
#include "src/core/SkPathView.h"
/** This is basically an iterator. It is initialized with an edge and a clip, /** This is basically an iterator. It is initialized with an edge and a clip,
and then next() is called until it returns kDone_Verb. and then next() is called until it returns kDone_Verb.
@ -31,7 +30,7 @@ public:
* Clips each segment from the path, and passes the result (in a clipper) to the * Clips each segment from the path, and passes the result (in a clipper) to the
* consume proc. * consume proc.
*/ */
static void ClipPath(const SkPathView& path, const SkRect& clip, bool canCullToTheRight, static void ClipPath(const SkPath& path, const SkRect& clip, bool canCullToTheRight,
void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx); void (*consume)(SkEdgeClipper*, bool newCtr, void* ctx), void* ctx);
private: private:

View File

@ -231,12 +231,6 @@ void SkPath::swap(SkPath& that) {
} }
} }
SkPathView SkPath::view() const {
return fPathRef->view(this->getFillType(), this->getConvexity());
}
///////////////////////////////////////////////////////////////////////////////////////////////////
bool SkPath::isInterpolatable(const SkPath& compare) const { bool SkPath::isInterpolatable(const SkPath& compare) const {
// need the same structure (verbs, conicweights) and same point-count // need the same structure (verbs, conicweights) and same point-count
return fPathRef->fPoints.count() == compare.fPathRef->fPoints.count() && return fPathRef->fPoints.count() == compare.fPathRef->fPoints.count() &&
@ -474,7 +468,7 @@ bool SkPath::isRect(SkRect* rect, bool* isClosed, SkPathDirection* direction) co
SkDEBUGCODE(this->validate();) SkDEBUGCODE(this->validate();)
int currVerb = 0; int currVerb = 0;
const SkPoint* pts = fPathRef->points(); const SkPoint* pts = fPathRef->points();
return SkPathPriv::IsRectContour(this->view(), false, &currVerb, &pts, isClosed, direction, rect); return SkPathPriv::IsRectContour(*this, false, &currVerb, &pts, isClosed, direction, rect);
} }
bool SkPath::isOval(SkRect* bounds) const { bool SkPath::isOval(SkRect* bounds) const {
@ -3428,7 +3422,7 @@ SkPath SkPath::Polygon(const SkPoint pts[], int count, bool isClosed,
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
bool SkPathPriv::IsRectContour(const SkPathView& path, bool allowPartial, int* currVerb, bool SkPathPriv::IsRectContour(const SkPath& path, bool allowPartial, int* currVerb,
const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction, const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
SkRect* rect) { SkRect* rect) {
int corners = 0; int corners = 0;
@ -3445,9 +3439,9 @@ bool SkPathPriv::IsRectContour(const SkPathView& path, bool allowPartial, int* c
bool closedOrMoved = false; bool closedOrMoved = false;
bool autoClose = false; bool autoClose = false;
bool insertClose = false; bool insertClose = false;
int verbCnt = path.fVerbs.count(); int verbCnt = path.fPathRef->countVerbs();
while (*currVerb < verbCnt && (!allowPartial || !autoClose)) { while (*currVerb < verbCnt && (!allowPartial || !autoClose)) {
uint8_t verb = insertClose ? (uint8_t) SkPath::kClose_Verb : path.fVerbs[*currVerb]; uint8_t verb = insertClose ? (uint8_t) SkPath::kClose_Verb : path.fPathRef->atVerb(*currVerb);
switch (verb) { switch (verb) {
case SkPath::kClose_Verb: case SkPath::kClose_Verb:
savePts = pts; savePts = pts;
@ -3569,9 +3563,10 @@ bool SkPathPriv::IsRectContour(const SkPathView& path, bool allowPartial, int* c
} }
bool SkPathPriv::IsNestedFillRects(const SkPathView& path, SkRect rects[2], SkPathDirection dirs[2]) { bool SkPathPriv::IsNestedFillRects(const SkPath& path, SkRect rects[2], SkPathDirection dirs[2]) {
SkDEBUGCODE(path.validate();)
int currVerb = 0; int currVerb = 0;
const SkPoint* pts = path.fPoints.begin(); const SkPoint* pts = path.fPathRef->points();
SkPathDirection testDirs[2]; SkPathDirection testDirs[2];
SkRect testRects[2]; SkRect testRects[2];
if (!IsRectContour(path, true, &currVerb, &pts, nullptr, &testDirs[0], &testRects[0])) { if (!IsRectContour(path, true, &currVerb, &pts, nullptr, &testDirs[0], &testRects[0])) {
@ -3706,7 +3701,7 @@ static SkPath clip(const SkPath& path, const SkHalfPlane& plane) {
SkPoint fPrev = {0,0}; SkPoint fPrev = {0,0};
} rec; } rec;
SkEdgeClipper::ClipPath(rotated.view(), clip, false, SkEdgeClipper::ClipPath(rotated, clip, false,
[](SkEdgeClipper* clipper, bool newCtr, void* ctx) { [](SkEdgeClipper* clipper, bool newCtr, void* ctx) {
Rec* rec = (Rec*)ctx; Rec* rec = (Rec*)ctx;

View File

@ -10,7 +10,6 @@
#include "include/core/SkPathBuilder.h" #include "include/core/SkPathBuilder.h"
#include "include/private/SkIDChangeListener.h" #include "include/private/SkIDChangeListener.h"
#include "src/core/SkPathView.h"
static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch"); static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch");
static_assert(1 == static_cast<int>(SkPathFillType::kEvenOdd), "fill_type_mismatch"); static_assert(1 == static_cast<int>(SkPathFillType::kEvenOdd), "fill_type_mismatch");
@ -154,13 +153,6 @@ public:
: path.fPathRef->verbsEnd(), : path.fPathRef->verbsEnd(),
path.fPathRef->points(), path.fPathRef->conicWeights()) { path.fPathRef->points(), path.fPathRef->conicWeights()) {
} }
Iterate(const SkPathView& path)
: Iterate(path.fVerbs.begin(),
// Don't allow iteration through non-finite points.
(!path.isFinite()) ? path.fVerbs.begin()
: path.fVerbs.end(),
path.fPoints.begin(), path.fWeights.begin()) {
}
Iterate(const uint8_t* verbsBegin, const uint8_t* verbsEnd, const SkPoint* points, Iterate(const uint8_t* verbsBegin, const uint8_t* verbsEnd, const SkPoint* points,
const SkScalar* weights) const SkScalar* weights)
: fVerbsBegin(verbsBegin), fVerbsEnd(verbsEnd), fPoints(points), fWeights(weights) { : fVerbsBegin(verbsBegin), fVerbsEnd(verbsEnd), fPoints(points), fWeights(weights) {
@ -339,7 +331,7 @@ public:
return true; return true;
} }
static bool IsRectContour(const SkPathView&, bool allowPartial, int* currVerb, static bool IsRectContour(const SkPath&, bool allowPartial, int* currVerb,
const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction, const SkPoint** ptsPtr, bool* isClosed, SkPathDirection* direction,
SkRect* rect); SkRect* rect);
@ -354,14 +346,9 @@ public:
@param dirs storage for SkPathDirection pair; may be nullptr @param dirs storage for SkPathDirection pair; may be nullptr
@return true if SkPath contains nested SkRect pair @return true if SkPath contains nested SkRect pair
*/ */
static bool IsNestedFillRects(const SkPathView&, SkRect rect[2], static bool IsNestedFillRects(const SkPath&, SkRect rect[2],
SkPathDirection dirs[2] = nullptr); SkPathDirection dirs[2] = nullptr);
static bool IsNestedFillRects(const SkPath& path, SkRect rect[2],
SkPathDirection dirs[2] = nullptr) {
return IsNestedFillRects(path.view(), rect, dirs);
}
static bool IsInverseFillType(SkPathFillType fill) { static bool IsInverseFillType(SkPathFillType fill) {
return (static_cast<int>(fill) & 2) != 0; return (static_cast<int>(fill) & 2) != 0;
} }
@ -444,8 +431,7 @@ class SkPathEdgeIter {
}; };
public: public:
SkPathEdgeIter(const SkPath&); SkPathEdgeIter(const SkPath& path);
SkPathEdgeIter(const SkPathView&);
SkScalar conicWeight() const { SkScalar conicWeight() const {
SkASSERT(fIsConic); SkASSERT(fIsConic);

View File

@ -13,7 +13,6 @@
#include "include/private/SkTo.h" #include "include/private/SkTo.h"
#include "src/core/SkBuffer.h" #include "src/core/SkBuffer.h"
#include "src/core/SkPathPriv.h" #include "src/core/SkPathPriv.h"
#include "src/core/SkPathView.h"
#include "src/core/SkSafeMath.h" #include "src/core/SkSafeMath.h"
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -684,21 +683,6 @@ bool SkPathRef::isValid() const {
////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////
#include "src/core/SkPathView.h"
SkPathView SkPathRef::view(SkPathFillType ft, SkPathConvexity ct) const {
return {
{ fPoints.begin(), fPoints.size() },
{ fVerbs.begin(), fVerbs.size() },
{ fConicWeights.begin(), fConicWeights.size() },
ft,
ct,
this->getBounds(), // don't use fBounds, in case our bounds are dirty
fSegmentMask,
this->isFinite(),
};
}
SkPathEdgeIter::SkPathEdgeIter(const SkPath& path) { SkPathEdgeIter::SkPathEdgeIter(const SkPath& path) {
fMoveToPtr = fPts = path.fPathRef->points(); fMoveToPtr = fPts = path.fPathRef->points();
fVerbs = path.fPathRef->verbsBegin(); fVerbs = path.fPathRef->verbsBegin();
@ -712,55 +696,3 @@ SkPathEdgeIter::SkPathEdgeIter(const SkPath& path) {
fNextIsNewContour = false; fNextIsNewContour = false;
SkDEBUGCODE(fIsConic = false;) SkDEBUGCODE(fIsConic = false;)
} }
SkPathEdgeIter::SkPathEdgeIter(const SkPathView& path) {
fMoveToPtr = fPts = path.fPoints.cbegin();
fVerbs = path.fVerbs.cbegin();
fVerbsStop = path.fVerbs.cend();
fConicWeights = path.fWeights.cbegin();
if (fConicWeights) {
fConicWeights -= 1; // begin one behind
}
fNeedsCloseLine = false;
fNextIsNewContour = false;
SkDEBUGCODE(fIsConic = false;)
}
bool SkPathView::isRect(SkRect* rect) const {
SkPathDirection direction;
bool isClosed;
int currVerb = 0;
const SkPoint* pts = fPoints.begin();
return SkPathPriv::IsRectContour(*this, false, &currVerb, &pts, &isClosed, &direction, rect);
}
#ifdef SK_DEBUG
void SkPathView::validate() const {
bool finite = SkScalarsAreFinite((const SkScalar*)fPoints.begin(), fPoints.count() * 2)
&& SkScalarsAreFinite( fWeights.begin(), fWeights.count());
SkASSERT(fIsFinite == finite);
if (fIsFinite) {
SkRect bounds;
bounds.setBounds(fPoints.begin(), fPoints.count());
SkASSERT(bounds == fBounds);
} else {
SkASSERT(fBounds.isEmpty());
}
unsigned mask = 0;
for (auto v : fVerbs) {
switch (static_cast<SkPathVerb>(v)) {
default: break;
case SkPathVerb::kLine: mask |= kLine_SkPathSegmentMask; break;
case SkPathVerb::kQuad: mask |= kQuad_SkPathSegmentMask; break;
case SkPathVerb::kConic: mask |= kConic_SkPathSegmentMask; break;
case SkPathVerb::kCubic: mask |= kCubic_SkPathSegmentMask; break;
}
}
SkASSERT(mask == fSegmentMask);
}
#endif

View File

@ -1,79 +0,0 @@
/*
* Copyright 2020 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#pragma once
#include "include/core/SkPathTypes.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/private/SkPathRef.h"
#include "src/core/SkSpan.h"
struct SkPathView {
SkPathView(SkSpan<const SkPoint> points, SkSpan<const uint8_t> verbs, SkSpan<const float> weights,
SkPathFillType ft, SkPathConvexity ct, const SkRect& bounds, unsigned segmentMask,
bool isFinite)
: fPoints(points)
, fVerbs(verbs)
, fWeights(weights)
, fBounds(bounds)
, fFillType(ft)
, fConvexity(ct)
, fSegmentMask(segmentMask)
, fIsFinite(isFinite)
{
this->validate();
}
bool isInverseFillType() const { return SkPathFillType_IsInverse(fFillType); }
bool isConvex() const { return fConvexity == SkPathConvexity::kConvex; }
bool isEmpty() const { return fPoints.size() == 0; }
bool isRect(SkRect*) const;
bool isFinite() const { return fIsFinite; }
SkSpan<const SkPoint> fPoints;
SkSpan<const uint8_t> fVerbs;
SkSpan<const float> fWeights;
SkRect fBounds;
SkPathFillType fFillType;
SkPathConvexity fConvexity;
uint8_t fSegmentMask;
bool fIsFinite;
#ifdef SK_DEBUG
void validate() const;
#else
void validate() const {}
#endif
};
static inline SkPathView SkPathView_triangle(const SkPoint pts[3], const SkRect& bounds) {
static constexpr uint8_t verbs[] = {
(uint8_t)SkPathVerb::kMove,
(uint8_t)SkPathVerb::kLine,
(uint8_t)SkPathVerb::kLine,
};
return SkPathView({pts, 3}, SkSpan(verbs), {},
SkPathFillType::kWinding, SkPathConvexity::kConvex,
bounds, kLine_SkPathSegmentMask, true);
}
static inline SkPathView SkPathView_quad(const SkPoint pts[4], const SkRect& bounds) {
static constexpr uint8_t verbs[] = {
(uint8_t)SkPathVerb::kMove,
(uint8_t)SkPathVerb::kLine,
(uint8_t)SkPathVerb::kLine,
(uint8_t)SkPathVerb::kLine,
};
return SkPathView({pts, 4}, SkSpan(verbs), {},
SkPathFillType::kWinding, SkPathConvexity::kConvex,
bounds, kLine_SkPathSegmentMask, true);
};

View File

@ -365,7 +365,7 @@ bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) {
return this->setEmpty(); return this->setEmpty();
} }
SkScan::FillPath(path.view(), clip, &builder); SkScan::FillPath(path, clip, &builder);
builder.done(); builder.done();
int count = builder.computeRunCount(); int count = builder.computeRunCount();

View File

@ -11,13 +11,12 @@
#include "include/core/SkRect.h" #include "include/core/SkRect.h"
#include "include/private/SkFixed.h" #include "include/private/SkFixed.h"
#include "src/core/SkPathView.h"
#include <atomic> #include <atomic>
class SkRasterClip; class SkRasterClip;
class SkRegion; class SkRegion;
class SkBlitter; class SkBlitter;
class SkPath;
/** Defines a fixed-point rectangle, identical to the integer SkIRect, but its /** Defines a fixed-point rectangle, identical to the integer SkIRect, but its
coordinates are treated as SkFixed rather than int32_t. coordinates are treated as SkFixed rather than int32_t.
@ -40,7 +39,7 @@ public:
typedef void (*HairRgnProc)(const SkPoint[], int count, const SkRegion*, SkBlitter*); typedef void (*HairRgnProc)(const SkPoint[], int count, const SkRegion*, SkBlitter*);
typedef void (*HairRCProc)(const SkPoint[], int count, const SkRasterClip&, SkBlitter*); typedef void (*HairRCProc)(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);
static void FillPath(const SkPathView&, const SkIRect&, SkBlitter*); static void FillPath(const SkPath&, const SkIRect&, SkBlitter*);
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// rasterclip // rasterclip
@ -50,8 +49,8 @@ public:
static void FillRect(const SkRect&, const SkRasterClip&, SkBlitter*); static void FillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
static void AntiFillRect(const SkRect&, const SkRasterClip&, SkBlitter*); static void AntiFillRect(const SkRect&, const SkRasterClip&, SkBlitter*);
static void AntiFillXRect(const SkXRect&, const SkRasterClip&, SkBlitter*); static void AntiFillXRect(const SkXRect&, const SkRasterClip&, SkBlitter*);
static void FillPath(const SkPathView&, const SkRasterClip&, SkBlitter*); static void FillPath(const SkPath&, const SkRasterClip&, SkBlitter*);
static void AntiFillPath(const SkPathView&, const SkRasterClip&, SkBlitter*); static void AntiFillPath(const SkPath&, const SkRasterClip&, SkBlitter*);
static void FrameRect(const SkRect&, const SkPoint& strokeSize, static void FrameRect(const SkRect&, const SkPoint& strokeSize,
const SkRasterClip&, SkBlitter*); const SkRasterClip&, SkBlitter*);
static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize, static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
@ -61,15 +60,15 @@ public:
static void AntiHairLine(const SkPoint[], int count, const SkRasterClip&, SkBlitter*); static void AntiHairLine(const SkPoint[], int count, const SkRasterClip&, SkBlitter*);
static void HairRect(const SkRect&, const SkRasterClip&, SkBlitter*); static void HairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
static void AntiHairRect(const SkRect&, const SkRasterClip&, SkBlitter*); static void AntiHairRect(const SkRect&, const SkRasterClip&, SkBlitter*);
static void HairPath(const SkPathView&, const SkRasterClip&, SkBlitter*); static void HairPath(const SkPath&, const SkRasterClip&, SkBlitter*);
static void AntiHairPath(const SkPathView&, const SkRasterClip&, SkBlitter*); static void AntiHairPath(const SkPath&, const SkRasterClip&, SkBlitter*);
static void HairSquarePath(const SkPathView&, const SkRasterClip&, SkBlitter*); static void HairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*);
static void AntiHairSquarePath(const SkPathView&, const SkRasterClip&, SkBlitter*); static void AntiHairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*);
static void HairRoundPath(const SkPathView&, const SkRasterClip&, SkBlitter*); static void HairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*);
static void AntiHairRoundPath(const SkPathView&, const SkRasterClip&, SkBlitter*); static void AntiHairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*);
// Needed by do_fill_path in SkScanPriv.h // Needed by do_fill_path in SkScanPriv.h
static void FillPath(const SkPathView&, const SkRegion& clip, SkBlitter*); static void FillPath(const SkPath&, const SkRegion& clip, SkBlitter*);
private: private:
friend class SkAAClip; friend class SkAAClip;
@ -80,16 +79,16 @@ private:
static void FillRect(const SkRect&, const SkRegion* clip, SkBlitter*); static void FillRect(const SkRect&, const SkRegion* clip, SkBlitter*);
static void AntiFillRect(const SkRect&, const SkRegion* clip, SkBlitter*); static void AntiFillRect(const SkRect&, const SkRegion* clip, SkBlitter*);
static void AntiFillXRect(const SkXRect&, const SkRegion*, SkBlitter*); static void AntiFillXRect(const SkXRect&, const SkRegion*, SkBlitter*);
static void AntiFillPath(const SkPathView&, const SkRegion& clip, SkBlitter*, bool forceRLE); static void AntiFillPath(const SkPath&, const SkRegion& clip, SkBlitter*, bool forceRLE);
static void FillTriangle(const SkPoint pts[], const SkRegion*, SkBlitter*); static void FillTriangle(const SkPoint pts[], const SkRegion*, SkBlitter*);
static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize, static void AntiFrameRect(const SkRect&, const SkPoint& strokeSize,
const SkRegion*, SkBlitter*); const SkRegion*, SkBlitter*);
static void HairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*); static void HairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*);
static void AntiHairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*); static void AntiHairLineRgn(const SkPoint[], int count, const SkRegion*, SkBlitter*);
static void AAAFillPath(const SkPathView& path, SkBlitter* blitter, const SkIRect& pathIR, static void AAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& pathIR,
const SkIRect& clipBounds, bool forceRLE); const SkIRect& clipBounds, bool forceRLE);
static void SAAFillPath(const SkPathView& path, SkBlitter* blitter, const SkIRect& pathIR, static void SAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& pathIR,
const SkIRect& clipBounds, bool forceRLE); const SkIRect& clipBounds, bool forceRLE);
}; };

View File

@ -33,7 +33,7 @@ private:
const SkIRect* fClipRect; const SkIRect* fClipRect;
}; };
void sk_fill_path(const SkPathView&, const SkIRect& clipRect, void sk_fill_path(const SkPath& path, const SkIRect& clipRect,
SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp, SkBlitter* blitter, int start_y, int stop_y, int shiftEdgesUp,
bool pathContainedInClip); bool pathContainedInClip);
@ -81,7 +81,7 @@ static EdgeType* backward_insert_start(EdgeType* prev, SkFixed x) {
} }
// Check if the path is a rect and fat enough after clipping; if so, blit it. // Check if the path is a rect and fat enough after clipping; if so, blit it.
static inline bool TryBlitFatAntiRect(SkBlitter* blitter, const SkPathView& path, const SkIRect& clip) { static inline bool TryBlitFatAntiRect(SkBlitter* blitter, const SkPath& path, const SkIRect& clip) {
SkRect rect; SkRect rect;
if (!path.isRect(&rect)) { if (!path.isRect(&rect)) {
return false; // not rect return false; // not rect

View File

@ -25,7 +25,7 @@
#include <utility> #include <utility>
#if defined(SK_DISABLE_AAA) #if defined(SK_DISABLE_AAA)
void SkScan::AAAFillPath(const SkPathView&, SkBlitter*, const SkIRect&, const SkIRect&, bool) { void SkScan::AAAFillPath(const SkPath&, SkBlitter*, const SkIRect&, const SkIRect&, bool) {
SkDEBUGFAIL("AAA Disabled"); SkDEBUGFAIL("AAA Disabled");
return; return;
} }
@ -1837,10 +1837,8 @@ static void aaa_walk_edges(SkAnalyticEdge* prevHead,
} }
} }
#include "src/core/SkPathView.h"
static SK_ALWAYS_INLINE void aaa_fill_path( static SK_ALWAYS_INLINE void aaa_fill_path(
const SkPathView& path, const SkPath& path,
const SkIRect& clipRect, const SkIRect& clipRect,
AdditiveBlitter* blitter, AdditiveBlitter* blitter,
int start_y, int start_y,
@ -1916,7 +1914,7 @@ static SK_ALWAYS_INLINE void aaa_fill_path(
// If we're using mask, then we have to limit the bound within the path bounds. // If we're using mask, then we have to limit the bound within the path bounds.
// Otherwise, the edge drift may access an invalid address inside the mask. // Otherwise, the edge drift may access an invalid address inside the mask.
SkIRect ir; SkIRect ir;
path.fBounds.roundOut(&ir); path.getBounds().roundOut(&ir);
leftBound = std::max(leftBound, SkIntToFixed(ir.fLeft)); leftBound = std::max(leftBound, SkIntToFixed(ir.fLeft));
rightBound = std::min(rightBound, SkIntToFixed(ir.fRight)); rightBound = std::min(rightBound, SkIntToFixed(ir.fRight));
} }
@ -1932,11 +1930,11 @@ static SK_ALWAYS_INLINE void aaa_fill_path(
// We skip intersection computation if there are many points which probably already // We skip intersection computation if there are many points which probably already
// give us enough fractional scan lines. // give us enough fractional scan lines.
bool skipIntersect = path.fPoints.count() > (stop_y - start_y) * 2; bool skipIntersect = path.countPoints() > (stop_y - start_y) * 2;
aaa_walk_edges(&headEdge, aaa_walk_edges(&headEdge,
&tailEdge, &tailEdge,
path.fFillType, path.getFillType(),
blitter, blitter,
start_y, start_y,
stop_y, stop_y,
@ -1949,7 +1947,7 @@ static SK_ALWAYS_INLINE void aaa_fill_path(
} }
} }
void SkScan::AAAFillPath(const SkPathView& path, void SkScan::AAAFillPath(const SkPath& path,
SkBlitter* blitter, SkBlitter* blitter,
const SkIRect& ir, const SkIRect& ir,
const SkIRect& clipBounds, const SkIRect& clipBounds,

View File

@ -602,18 +602,18 @@ constexpr int kSampleSize = 8;
constexpr SkScalar kComplexityThreshold = 0.25; constexpr SkScalar kComplexityThreshold = 0.25;
#endif #endif
static void compute_complexity(const SkPathView& path, SkScalar& avgLength, SkScalar& complexity) { static void compute_complexity(const SkPath& path, SkScalar& avgLength, SkScalar& complexity) {
int n = path.fPoints.count(); int n = path.countPoints();
if (n < kSampleSize || path.fBounds.isEmpty()) { if (n < kSampleSize || path.getBounds().isEmpty()) {
// set to invalid value to indicate that we failed to compute // set to invalid value to indicate that we failed to compute
avgLength = complexity = -1; avgLength = complexity = -1;
return; return;
} }
SkScalar sumLength = 0; SkScalar sumLength = 0;
SkPoint lastPoint = path.fPoints[0]; SkPoint lastPoint = path.getPoint(0);
for(int i = 1; i < kSampleSize; ++i) { for(int i = 1; i < kSampleSize; ++i) {
SkPoint point = path.fPoints[i]; SkPoint point = path.getPoint(i);
sumLength += SkPoint::Distance(lastPoint, point); sumLength += SkPoint::Distance(lastPoint, point);
lastPoint = point; lastPoint = point;
} }
@ -621,21 +621,21 @@ static void compute_complexity(const SkPathView& path, SkScalar& avgLength, SkSc
auto sqr = [](SkScalar x) { return x*x; }; auto sqr = [](SkScalar x) { return x*x; };
SkScalar diagonalSqr = sqr(path.fBounds.width()) + sqr(path.fBounds.height()); SkScalar diagonalSqr = sqr(path.getBounds().width()) + sqr(path.getBounds().height());
// If the path consists of random line segments, the number of intersections should be // If the path consists of random line segments, the number of intersections should be
// proportional to this. // proportional to this.
SkScalar intersections = sk_ieee_float_divide(sqr(n) * sqr(avgLength), diagonalSqr); SkScalar intersections = sk_ieee_float_divide(sqr(n) * sqr(avgLength), diagonalSqr);
// The number of intersections per scanline should be proportional to this number. // The number of intersections per scanline should be proportional to this number.
complexity = sk_ieee_float_divide(intersections, path.fBounds.height()); complexity = sk_ieee_float_divide(intersections, path.getBounds().height());
if (sk_float_isnan(complexity)) { // it may be possible to have 0.0 / 0.0; inf is fine for us. if (sk_float_isnan(complexity)) { // it may be possible to have 0.0 / 0.0; inf is fine for us.
complexity = -1; complexity = -1;
} }
} }
static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar complexity) { static bool ShouldUseAAA(const SkPath& path, SkScalar avgLength, SkScalar complexity) {
#if defined(SK_DISABLE_AAA) #if defined(SK_DISABLE_AAA)
return false; return false;
#else #else
@ -650,16 +650,16 @@ static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar co
} }
#ifdef SK_SUPPORT_LEGACY_AAA_CHOICE #ifdef SK_SUPPORT_LEGACY_AAA_CHOICE
const SkRect& bounds = path.fBounds; const SkRect& bounds = path.getBounds();
// When the path have so many points compared to the size of its // When the path have so many points compared to the size of its
// bounds/resolution, it indicates that the path is not quite smooth in // bounds/resolution, it indicates that the path is not quite smooth in
// the current resolution: the expected number of turning points in // the current resolution: the expected number of turning points in
// every pixel row/column is significantly greater than zero. Hence // every pixel row/column is significantly greater than zero. Hence
// Aanlytic AA is not likely to produce visible quality improvements, // Aanlytic AA is not likely to produce visible quality improvements,
// and Analytic AA might be slower than supersampling. // and Analytic AA might be slower than supersampling.
return path.fPoints.count() < std::max(bounds.width(), bounds.height()) / 2 - 10; return path.countPoints() < std::max(bounds.width(), bounds.height()) / 2 - 10;
#else #else
if (path.fPoints.count() >= path.fBounds.height()) { if (path.countPoints() >= path.getBounds().height()) {
// SAA is faster than AAA in this case even if there are no // SAA is faster than AAA in this case even if there are no
// intersections because AAA will have too many scan lines. See // intersections because AAA will have too many scan lines. See
// skbug.com/8272 // skbug.com/8272
@ -671,7 +671,7 @@ static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar co
#endif #endif
} }
void SkScan::SAAFillPath(const SkPathView& path, SkBlitter* blitter, const SkIRect& ir, void SkScan::SAAFillPath(const SkPath& path, SkBlitter* blitter, const SkIRect& ir,
const SkIRect& clipBounds, bool forceRLE) { const SkIRect& clipBounds, bool forceRLE) {
bool containedInClip = clipBounds.contains(ir); bool containedInClip = clipBounds.contains(ir);
bool isInverse = path.isInverseFillType(); bool isInverse = path.isInverseFillType();
@ -680,7 +680,7 @@ void SkScan::SAAFillPath(const SkPathView& path, SkBlitter* blitter, const SkIRe
// if we're an inverse filltype // if we're an inverse filltype
if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) { if (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) {
MaskSuperBlitter superBlit(blitter, ir, clipBounds, isInverse); MaskSuperBlitter superBlit(blitter, ir, clipBounds, isInverse);
SkASSERT(SkIntToScalar(ir.fTop) <= path.fBounds.fTop); SkASSERT(SkIntToScalar(ir.fTop) <= path.getBounds().fTop);
sk_fill_path(path, clipBounds, &superBlit, ir.fTop, ir.fBottom, SHIFT, containedInClip); sk_fill_path(path, clipBounds, &superBlit, ir.fTop, ir.fBottom, SHIFT, containedInClip);
} else { } else {
SuperBlitter superBlit(blitter, ir, clipBounds, isInverse); SuperBlitter superBlit(blitter, ir, clipBounds, isInverse);
@ -711,14 +711,14 @@ static int rect_overflows_short_shift(SkIRect rect, int shift) {
overflows_short_shift(rect.fBottom, shift); overflows_short_shift(rect.fBottom, shift);
} }
void SkScan::AntiFillPath(const SkPathView& path, const SkRegion& origClip, void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip,
SkBlitter* blitter, bool forceRLE) { SkBlitter* blitter, bool forceRLE) {
if (origClip.isEmpty()) { if (origClip.isEmpty()) {
return; return;
} }
const bool isInverse = path.isInverseFillType(); const bool isInverse = path.isInverseFillType();
SkIRect ir = safeRoundOut(path.fBounds); SkIRect ir = safeRoundOut(path.getBounds());
if (ir.isEmpty()) { if (ir.isEmpty()) {
if (isInverse) { if (isInverse) {
blitter->blitRegion(origClip); blitter->blitRegion(origClip);
@ -802,7 +802,7 @@ void SkScan::AntiFillPath(const SkPathView& path, const SkRegion& origClip,
#include "src/core/SkRasterClip.h" #include "src/core/SkRasterClip.h"
void SkScan::FillPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::FillPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
if (clip.isEmpty() || !path.isFinite()) { if (clip.isEmpty() || !path.isFinite()) {
return; return;
} }
@ -819,7 +819,7 @@ void SkScan::FillPath(const SkPathView& path, const SkRasterClip& clip, SkBlitte
} }
} }
void SkScan::AntiFillPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::AntiFillPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
if (clip.isEmpty() || !path.isFinite()) { if (clip.isEmpty() || !path.isFinite()) {
return; return;
} }

View File

@ -507,7 +507,7 @@ void extend_pts(SkPath::Verb prevVerb, SkPath::Verb nextVerb, SkPoint* pts, int
} }
template <SkPaint::Cap capStyle> template <SkPaint::Cap capStyle>
void hair_path(const SkPathView& path, const SkRasterClip& rclip, SkBlitter* blitter, void hair_path(const SkPath& path, const SkRasterClip& rclip, SkBlitter* blitter,
SkScan::HairRgnProc lineproc) { SkScan::HairRgnProc lineproc) {
if (path.isEmpty()) { if (path.isEmpty()) {
return; return;
@ -521,7 +521,7 @@ void hair_path(const SkPathView& path, const SkRasterClip& rclip, SkBlitter* bli
{ {
const int capOut = SkPaint::kButt_Cap == capStyle ? 1 : 2; const int capOut = SkPaint::kButt_Cap == capStyle ? 1 : 2;
const SkIRect ibounds = path.fBounds.roundOut().makeOutset(capOut, capOut); const SkIRect ibounds = path.getBounds().roundOut().makeOutset(capOut, capOut);
if (rclip.quickReject(ibounds)) { if (rclip.quickReject(ibounds)) {
return; return;
} }
@ -643,27 +643,27 @@ void hair_path(const SkPathView& path, const SkRasterClip& rclip, SkBlitter* bli
} }
} }
void SkScan::HairPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::HairPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
hair_path<SkPaint::kButt_Cap>(path, clip, blitter, SkScan::HairLineRgn); hair_path<SkPaint::kButt_Cap>(path, clip, blitter, SkScan::HairLineRgn);
} }
void SkScan::AntiHairPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::AntiHairPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
hair_path<SkPaint::kButt_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn); hair_path<SkPaint::kButt_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
} }
void SkScan::HairSquarePath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::HairSquarePath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
hair_path<SkPaint::kSquare_Cap>(path, clip, blitter, SkScan::HairLineRgn); hair_path<SkPaint::kSquare_Cap>(path, clip, blitter, SkScan::HairLineRgn);
} }
void SkScan::AntiHairSquarePath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::AntiHairSquarePath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
hair_path<SkPaint::kSquare_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn); hair_path<SkPaint::kSquare_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
} }
void SkScan::HairRoundPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::HairRoundPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
hair_path<SkPaint::kRound_Cap>(path, clip, blitter, SkScan::HairLineRgn); hair_path<SkPaint::kRound_Cap>(path, clip, blitter, SkScan::HairLineRgn);
} }
void SkScan::AntiHairRoundPath(const SkPathView& path, const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::AntiHairRoundPath(const SkPath& path, const SkRasterClip& clip, SkBlitter* blitter) {
hair_path<SkPaint::kRound_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn); hair_path<SkPaint::kRound_Cap>(path, clip, blitter, SkScan::AntiHairLineRgn);
} }

View File

@ -391,10 +391,8 @@ static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) {
return list[0]; return list[0];
} }
#include "src/core/SkPathView.h"
// clipRect has not been shifted up // clipRect has not been shifted up
void sk_fill_path(const SkPathView& path, const SkIRect& clipRect, SkBlitter* blitter, void sk_fill_path(const SkPath& path, const SkIRect& clipRect, SkBlitter* blitter,
int start_y, int stop_y, int shiftEdgesUp, bool pathContainedInClip) { int start_y, int stop_y, int shiftEdgesUp, bool pathContainedInClip) {
SkASSERT(blitter); SkASSERT(blitter);
@ -472,7 +470,8 @@ void sk_fill_path(const SkPathView& path, const SkIRect& clipRect, SkBlitter* bl
if (path.isConvex() && (nullptr == proc) && count >= 2) { if (path.isConvex() && (nullptr == proc) && count >= 2) {
walk_simple_edges(&headEdge, blitter, start_y, stop_y); walk_simple_edges(&headEdge, blitter, start_y, stop_y);
} else { } else {
walk_edges(&headEdge, path.fFillType, blitter, start_y, stop_y, proc, shiftedClip.right()); walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc,
shiftedClip.right());
} }
} }
@ -614,7 +613,8 @@ static SkIRect conservative_round_to_int(const SkRect& src) {
}; };
} }
void SkScan::FillPath(const SkPathView& path, const SkRegion& origClip, SkBlitter* blitter) { void SkScan::FillPath(const SkPath& path, const SkRegion& origClip,
SkBlitter* blitter) {
if (origClip.isEmpty()) { if (origClip.isEmpty()) {
return; return;
} }
@ -632,7 +632,7 @@ void SkScan::FillPath(const SkPathView& path, const SkRegion& origClip, SkBlitte
// don't reference "origClip" any more, just use clipPtr // don't reference "origClip" any more, just use clipPtr
SkRect bounds = path.fBounds; SkRect bounds = path.getBounds();
bool irPreClipped = false; bool irPreClipped = false;
if (!SkRectPriv::MakeLargeS32().contains(bounds)) { if (!SkRectPriv::MakeLargeS32().contains(bounds)) {
if (!bounds.intersect(SkRectPriv::MakeLargeS32())) { if (!bounds.intersect(SkRectPriv::MakeLargeS32())) {
@ -670,7 +670,7 @@ void SkScan::FillPath(const SkPathView& path, const SkRegion& origClip, SkBlitte
} }
} }
void SkScan::FillPath(const SkPathView& path, const SkIRect& ir, void SkScan::FillPath(const SkPath& path, const SkIRect& ir,
SkBlitter* blitter) { SkBlitter* blitter) {
SkRegion rgn(ir); SkRegion rgn(ir);
FillPath(path, rgn, blitter); FillPath(path, rgn, blitter);
@ -737,7 +737,8 @@ static void sk_fill_triangle(const SkPoint pts[], const SkIRect* clipRect,
walk_simple_edges(&headEdge, blitter, start_y, stop_y); walk_simple_edges(&headEdge, blitter, start_y, stop_y);
} }
void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip, SkBlitter* blitter) { void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip,
SkBlitter* blitter) {
if (clip.isEmpty()) { if (clip.isEmpty()) {
return; return;
} }
@ -749,7 +750,9 @@ void SkScan::FillTriangle(const SkPoint pts[], const SkRasterClip& clip, SkBlitt
// Use FixedMax/2 as the limit so we can subtract two edges and still store that in Fixed. // Use FixedMax/2 as the limit so we can subtract two edges and still store that in Fixed.
const SkScalar limit = SK_MaxS16 >> 1; const SkScalar limit = SK_MaxS16 >> 1;
if (!SkRect::MakeLTRB(-limit, -limit, limit, limit).contains(r)) { if (!SkRect::MakeLTRB(-limit, -limit, limit, limit).contains(r)) {
FillPath(SkPathView_triangle(pts, r), clip, blitter); SkPath path;
path.addPoly(pts, 3, false);
FillPath(path, clip, blitter);
return; return;
} }

View File

@ -42,7 +42,7 @@ DEF_TEST(FillPathInverse, reporter) {
SkIntToScalar(width), 0.0f) SkIntToScalar(width), 0.0f)
.close() .close()
.setFillType(SkPathFillType::kInverseWinding); .setFillType(SkPathFillType::kInverseWinding);
SkScan::FillPath(path.view(), clip, &blitter); SkScan::FillPath(path, clip, &blitter);
REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines); REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines);
} }

View File

@ -22,7 +22,6 @@
#include "src/core/SkAutoMalloc.h" #include "src/core/SkAutoMalloc.h"
#include "src/core/SkGeometry.h" #include "src/core/SkGeometry.h"
#include "src/core/SkPathPriv.h" #include "src/core/SkPathPriv.h"
#include "src/core/SkPathView.h"
#include "src/core/SkReadBuffer.h" #include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h" #include "src/core/SkWriteBuffer.h"
#include "tests/Test.h" #include "tests/Test.h"
@ -5658,18 +5657,12 @@ static void test_edger(skiatest::Reporter* r,
} }
SkPathEdgeIter iter(path); SkPathEdgeIter iter(path);
SkPathEdgeIter iter2(path.view());
for (auto v : expected) { for (auto v : expected) {
auto e = iter.next(); auto e = iter.next();
REPORTER_ASSERT(r, e); REPORTER_ASSERT(r, e);
REPORTER_ASSERT(r, SkPathEdgeIter::EdgeToVerb(e.fEdge) == v); REPORTER_ASSERT(r, SkPathEdgeIter::EdgeToVerb(e.fEdge) == v);
e = iter2.next();
REPORTER_ASSERT(r, e);
REPORTER_ASSERT(r, SkPathEdgeIter::EdgeToVerb(e.fEdge) == v);
} }
REPORTER_ASSERT(r, !iter.next()); REPORTER_ASSERT(r, !iter.next());
REPORTER_ASSERT(r, !iter2.next());
} }
DEF_TEST(pathedger, r) { DEF_TEST(pathedger, r) {