From 71f12666647b40c6d0a95ab75a5c77095a171e54 Mon Sep 17 00:00:00 2001 From: Mike Klein Date: Wed, 28 Oct 2020 09:07:09 -0500 Subject: [PATCH] Revert "SkPathView for ownerless (can live on stack) SkPaths" This reverts commit 375721d7bba3204169b4eb9927774436c9d4daea. 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 Commit-Queue: Mike Klein --- include/core/SkPath.h | 3 -- include/private/SkPathRef.h | 4 -- samplecode/SampleClip.cpp | 2 +- src/core/SkAAClip.cpp | 5 +-- src/core/SkDraw.cpp | 4 +- src/core/SkDraw_atlas.cpp | 13 +++--- src/core/SkEdgeBuilder.cpp | 11 +++-- src/core/SkEdgeBuilder.h | 9 ++-- src/core/SkEdgeClipper.cpp | 7 ++-- src/core/SkEdgeClipper.h | 3 +- src/core/SkPath.cpp | 21 ++++------ src/core/SkPathPriv.h | 20 ++------- src/core/SkPathRef.cpp | 68 ------------------------------- src/core/SkPathView.h | 79 ------------------------------------ src/core/SkRegion_path.cpp | 2 +- src/core/SkScan.h | 29 +++++++------ src/core/SkScanPriv.h | 4 +- src/core/SkScan_AAAPath.cpp | 14 +++---- src/core/SkScan_AntiPath.cpp | 34 ++++++++-------- src/core/SkScan_Hairline.cpp | 16 ++++---- src/core/SkScan_Path.cpp | 21 ++++++---- tests/FillPathTest.cpp | 2 +- tests/PathTest.cpp | 7 ---- 23 files changed, 99 insertions(+), 279 deletions(-) delete mode 100644 src/core/SkPathView.h diff --git a/include/core/SkPath.h b/include/core/SkPath.h index 89c2736ce2..3d478dca0f 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -18,7 +18,6 @@ class SkAutoPathBoundsUpdate; class SkData; class SkRRect; -struct SkPathView; class SkWStream; // WIP -- define this locally, and fix call-sites to use SkPathBuilder (skbug.com/9000) @@ -1540,8 +1539,6 @@ public: Verb autoClose(SkPoint pts[2]); }; - SkPathView view() const; - private: /** \class SkPath::RangeIter Iterates through a raw range of path verbs, points, and conics. All values are returned diff --git a/include/private/SkPathRef.h b/include/private/SkPathRef.h index af6aadd1ca..389a5a1ec2 100644 --- a/include/private/SkPathRef.h +++ b/include/private/SkPathRef.h @@ -9,7 +9,6 @@ #define SkPathRef_DEFINED #include "include/core/SkMatrix.h" -#include "include/core/SkPathTypes.h" #include "include/core/SkPoint.h" #include "include/core/SkRRect.h" #include "include/core/SkRect.h" @@ -24,7 +23,6 @@ #include #include -struct SkPathView; class SkRBuffer; class SkWBuffer; @@ -352,8 +350,6 @@ public: bool isValid() const; SkDEBUGCODE(void validate() const { SkASSERT(this->isValid()); } ) - SkPathView view(SkPathFillType, SkPathConvexity) const; - private: enum SerializationOffsets { kLegacyRRectOrOvalStartIdx_SerializationShift = 28, // requires 3 bits, ignored. diff --git a/samplecode/SampleClip.cpp b/samplecode/SampleClip.cpp index 443e462711..4a6c25d62a 100644 --- a/samplecode/SampleClip.cpp +++ b/samplecode/SampleClip.cpp @@ -227,7 +227,7 @@ static SkPath clip(const SkPath& path, SkPoint p0, SkPoint p1) { SkPoint fPrev = {0, 0}; } rec; - SkEdgeClipper::ClipPath(rotated.view(), clip, false, + SkEdgeClipper::ClipPath(rotated, clip, false, [](SkEdgeClipper* clipper, bool newCtr, void* ctx) { Rec* rec = (Rec*)ctx; diff --git a/src/core/SkAAClip.cpp b/src/core/SkAAClip.cpp index 917a4a61e1..c8764e27bd 100644 --- a/src/core/SkAAClip.cpp +++ b/src/core/SkAAClip.cpp @@ -1334,12 +1334,11 @@ bool SkAAClip::setPath(const SkPath& path, const SkRegion* clip, bool doAA) { Builder builder(ibounds); BuilderBlitter blitter(&builder); - const SkPathView view = path.view(); if (doAA) { - SkScan::AntiFillPath(view, snugClip, &blitter, true); + SkScan::AntiFillPath(path, snugClip, &blitter, true); } else { - SkScan::FillPath(view, snugClip, &blitter); + SkScan::FillPath(path, snugClip, &blitter); } blitter.finish(); diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 283ba18388..858995fe7e 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -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 (paint.isAntiAlias()) { 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, diff --git a/src/core/SkDraw_atlas.cpp b/src/core/SkDraw_atlas.cpp index 77285a41b3..077486f926 100644 --- a/src/core/SkDraw_atlas.cpp +++ b/src/core/SkDraw_atlas.cpp @@ -22,7 +22,7 @@ #include "src/core/SkScan.h" 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()) { SkRect dr; ctm.mapRect(&dr, r); @@ -32,10 +32,9 @@ static void fill_rect(const SkMatrix& ctm, const SkRasterClip& rc, r.toQuad(pts); ctm.mapPoints(pts, pts, 4); - SkRect bounds; - bounds.setBounds(pts, 4); - - SkScan::FillPath(SkPathView_quad(pts, bounds), rc, blitter); + scratchPath->rewind(); + scratchPath->addPoly(pts, 4, true); + SkScan::FillPath(*scratchPath, 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, fRC->clipShader())) { + SkPath scratchPath; + for (int i = 0; i < count; ++i) { if (colors) { 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()); if (updator->update(mx, nullptr)) { - fill_rect(mx, *fRC, textures[i], blitter); + fill_rect(mx, *fRC, textures[i], blitter, &scratchPath); } } } diff --git a/src/core/SkEdgeBuilder.cpp b/src/core/SkEdgeBuilder.cpp index b3df8a53e4..b11e4bd13d 100644 --- a/src/core/SkEdgeBuilder.cpp +++ b/src/core/SkEdgeBuilder.cpp @@ -14,7 +14,6 @@ #include "src/core/SkGeometry.h" #include "src/core/SkLineClipper.h" #include "src/core/SkPathPriv.h" -#include "src/core/SkPathView.h" #include "src/core/SkSafeMath.h" 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? -int SkEdgeBuilder::buildPoly(const SkPathView& path, const SkIRect* iclip, bool canCullToTheRight) { - size_t maxEdgeCount = path.fPoints.size(); +int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, bool canCullToTheRight) { + size_t maxEdgeCount = path.countPoints(); if (iclip) { // clipping can turn 1 line into (up to) kMaxClippedLineSegments, since // 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); } -int SkEdgeBuilder::build(const SkPathView& path, const SkIRect* iclip, bool canCullToTheRight) { +int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, bool canCullToTheRight) { SkAutoConicToQuads quadder; const SkScalar conicTol = SK_Scalar1 / 4; 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; } -int SkEdgeBuilder::buildEdges(const SkPathView& path, +int SkEdgeBuilder::buildEdges(const SkPath& path, const SkIRect* shiftedClip) { // If we're convex, then we need both edges, even if the right edge is past the clip. const bool canCullToTheRight = !path.isConvex(); // We can use our buildPoly() optimization if all the segments are lines. // (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->build (path, shiftedClip, canCullToTheRight); diff --git a/src/core/SkEdgeBuilder.h b/src/core/SkEdgeBuilder.h index 44e9d75702..5fb7c62522 100644 --- a/src/core/SkEdgeBuilder.h +++ b/src/core/SkEdgeBuilder.h @@ -13,11 +13,12 @@ #include "src/core/SkArenaAlloc.h" #include "src/core/SkEdge.h" -struct SkPathView; +class SkPath; class SkEdgeBuilder { public: - int buildEdges(const SkPathView&, const SkIRect* shiftedClip); + int buildEdges(const SkPath& path, + const SkIRect* shiftedClip); protected: SkEdgeBuilder() = default; @@ -36,8 +37,8 @@ protected: }; private: - int build (const SkPathView&, const SkIRect* clip, bool clipToTheRight); - int buildPoly(const SkPathView&, const SkIRect* clip, bool clipToTheRight); + int build (const SkPath& path, 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 SkRect recoverClip(const SkIRect&) const = 0; diff --git a/src/core/SkEdgeClipper.cpp b/src/core/SkEdgeClipper.cpp index c5ce792165..eb147f7512 100644 --- a/src/core/SkEdgeClipper.cpp +++ b/src/core/SkEdgeClipper.cpp @@ -560,13 +560,14 @@ void sk_assert_monotonic_x(const SkPoint pts[], int count) { #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) { - SkASSERT(view.isFinite()); + SkASSERT(path.isFinite()); + SkAutoConicToQuads quadder; const SkScalar conicTol = SK_Scalar1 / 4; - SkPathEdgeIter iter(view); + SkPathEdgeIter iter(path); SkEdgeClipper clipper(canCullToTheRight); while (auto e = iter.next()) { diff --git a/src/core/SkEdgeClipper.h b/src/core/SkEdgeClipper.h index e1eebbca08..4d3a87cd9f 100644 --- a/src/core/SkEdgeClipper.h +++ b/src/core/SkEdgeClipper.h @@ -10,7 +10,6 @@ #define SkEdgeClipper_DEFINED #include "include/core/SkPath.h" -#include "src/core/SkPathView.h" /** This is basically an iterator. It is initialized with an edge and a clip, 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 * 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); private: diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index d7fb2dc46c..a067a29210 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -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 { // need the same structure (verbs, conicweights) and same point-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();) int currVerb = 0; 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 { @@ -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, SkRect* rect) { int corners = 0; @@ -3445,9 +3439,9 @@ bool SkPathPriv::IsRectContour(const SkPathView& path, bool allowPartial, int* c bool closedOrMoved = false; bool autoClose = false; bool insertClose = false; - int verbCnt = path.fVerbs.count(); + int verbCnt = path.fPathRef->countVerbs(); 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) { case SkPath::kClose_Verb: 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; - const SkPoint* pts = path.fPoints.begin(); + const SkPoint* pts = path.fPathRef->points(); SkPathDirection testDirs[2]; SkRect testRects[2]; 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}; } rec; - SkEdgeClipper::ClipPath(rotated.view(), clip, false, + SkEdgeClipper::ClipPath(rotated, clip, false, [](SkEdgeClipper* clipper, bool newCtr, void* ctx) { Rec* rec = (Rec*)ctx; diff --git a/src/core/SkPathPriv.h b/src/core/SkPathPriv.h index f9f6565d19..93d0003a48 100644 --- a/src/core/SkPathPriv.h +++ b/src/core/SkPathPriv.h @@ -10,7 +10,6 @@ #include "include/core/SkPathBuilder.h" #include "include/private/SkIDChangeListener.h" -#include "src/core/SkPathView.h" static_assert(0 == static_cast(SkPathFillType::kWinding), "fill_type_mismatch"); static_assert(1 == static_cast(SkPathFillType::kEvenOdd), "fill_type_mismatch"); @@ -154,13 +153,6 @@ public: : path.fPathRef->verbsEnd(), 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, const SkScalar* weights) : fVerbsBegin(verbsBegin), fVerbsEnd(verbsEnd), fPoints(points), fWeights(weights) { @@ -339,7 +331,7 @@ public: 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, SkRect* rect); @@ -354,14 +346,9 @@ public: @param dirs storage for SkPathDirection pair; may be nullptr @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); - static bool IsNestedFillRects(const SkPath& path, SkRect rect[2], - SkPathDirection dirs[2] = nullptr) { - return IsNestedFillRects(path.view(), rect, dirs); - } - static bool IsInverseFillType(SkPathFillType fill) { return (static_cast(fill) & 2) != 0; } @@ -444,8 +431,7 @@ class SkPathEdgeIter { }; public: - SkPathEdgeIter(const SkPath&); - SkPathEdgeIter(const SkPathView&); + SkPathEdgeIter(const SkPath& path); SkScalar conicWeight() const { SkASSERT(fIsConic); diff --git a/src/core/SkPathRef.cpp b/src/core/SkPathRef.cpp index cf5ce0f01f..88a735383e 100644 --- a/src/core/SkPathRef.cpp +++ b/src/core/SkPathRef.cpp @@ -13,7 +13,6 @@ #include "include/private/SkTo.h" #include "src/core/SkBuffer.h" #include "src/core/SkPathPriv.h" -#include "src/core/SkPathView.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) { fMoveToPtr = fPts = path.fPathRef->points(); fVerbs = path.fPathRef->verbsBegin(); @@ -712,55 +696,3 @@ SkPathEdgeIter::SkPathEdgeIter(const SkPath& path) { fNextIsNewContour = 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(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 diff --git a/src/core/SkPathView.h b/src/core/SkPathView.h deleted file mode 100644 index 41c4a93f38..0000000000 --- a/src/core/SkPathView.h +++ /dev/null @@ -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 points, SkSpan verbs, SkSpan 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 fPoints; - SkSpan fVerbs; - SkSpan 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); -}; diff --git a/src/core/SkRegion_path.cpp b/src/core/SkRegion_path.cpp index 4484d6c6c1..0ec49bcab1 100644 --- a/src/core/SkRegion_path.cpp +++ b/src/core/SkRegion_path.cpp @@ -365,7 +365,7 @@ bool SkRegion::setPath(const SkPath& path, const SkRegion& clip) { return this->setEmpty(); } - SkScan::FillPath(path.view(), clip, &builder); + SkScan::FillPath(path, clip, &builder); builder.done(); int count = builder.computeRunCount(); diff --git a/src/core/SkScan.h b/src/core/SkScan.h index e9ee32e299..a1db6e5e6d 100644 --- a/src/core/SkScan.h +++ b/src/core/SkScan.h @@ -11,13 +11,12 @@ #include "include/core/SkRect.h" #include "include/private/SkFixed.h" -#include "src/core/SkPathView.h" - #include class SkRasterClip; class SkRegion; class SkBlitter; +class SkPath; /** Defines a fixed-point rectangle, identical to the integer SkIRect, but its 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 (*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 @@ -50,8 +49,8 @@ public: static void FillRect(const SkRect&, const SkRasterClip&, SkBlitter*); static void AntiFillRect(const SkRect&, const SkRasterClip&, SkBlitter*); static void AntiFillXRect(const SkXRect&, const SkRasterClip&, SkBlitter*); - static void FillPath(const SkPathView&, const SkRasterClip&, SkBlitter*); - static void AntiFillPath(const SkPathView&, const SkRasterClip&, SkBlitter*); + static void FillPath(const SkPath&, const SkRasterClip&, SkBlitter*); + static void AntiFillPath(const SkPath&, const SkRasterClip&, SkBlitter*); static void FrameRect(const SkRect&, const SkPoint& strokeSize, const SkRasterClip&, SkBlitter*); 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 HairRect(const SkRect&, const SkRasterClip&, SkBlitter*); static void AntiHairRect(const SkRect&, const SkRasterClip&, SkBlitter*); - static void HairPath(const SkPathView&, const SkRasterClip&, SkBlitter*); - static void AntiHairPath(const SkPathView&, const SkRasterClip&, SkBlitter*); - static void HairSquarePath(const SkPathView&, const SkRasterClip&, SkBlitter*); - static void AntiHairSquarePath(const SkPathView&, const SkRasterClip&, SkBlitter*); - static void HairRoundPath(const SkPathView&, const SkRasterClip&, SkBlitter*); - static void AntiHairRoundPath(const SkPathView&, const SkRasterClip&, SkBlitter*); + static void HairPath(const SkPath&, const SkRasterClip&, SkBlitter*); + static void AntiHairPath(const SkPath&, const SkRasterClip&, SkBlitter*); + static void HairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*); + static void AntiHairSquarePath(const SkPath&, const SkRasterClip&, SkBlitter*); + static void HairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*); + static void AntiHairRoundPath(const SkPath&, const SkRasterClip&, SkBlitter*); // 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: friend class SkAAClip; @@ -80,16 +79,16 @@ private: static void FillRect(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 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 AntiFrameRect(const SkRect&, const SkPoint& strokeSize, 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 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); - 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); }; diff --git a/src/core/SkScanPriv.h b/src/core/SkScanPriv.h index 62f62b9a3e..2bec85f7b8 100644 --- a/src/core/SkScanPriv.h +++ b/src/core/SkScanPriv.h @@ -33,7 +33,7 @@ private: 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, 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. -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; if (!path.isRect(&rect)) { return false; // not rect diff --git a/src/core/SkScan_AAAPath.cpp b/src/core/SkScan_AAAPath.cpp index 4f23909f18..81e6de0408 100644 --- a/src/core/SkScan_AAAPath.cpp +++ b/src/core/SkScan_AAAPath.cpp @@ -25,7 +25,7 @@ #include #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"); 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( - const SkPathView& path, + const SkPath& path, const SkIRect& clipRect, AdditiveBlitter* blitter, 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. // Otherwise, the edge drift may access an invalid address inside the mask. SkIRect ir; - path.fBounds.roundOut(&ir); + path.getBounds().roundOut(&ir); leftBound = std::max(leftBound, SkIntToFixed(ir.fLeft)); 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 // 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, &tailEdge, - path.fFillType, + path.getFillType(), blitter, start_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, const SkIRect& ir, const SkIRect& clipBounds, diff --git a/src/core/SkScan_AntiPath.cpp b/src/core/SkScan_AntiPath.cpp index 82d430420d..447b735a3d 100644 --- a/src/core/SkScan_AntiPath.cpp +++ b/src/core/SkScan_AntiPath.cpp @@ -602,18 +602,18 @@ constexpr int kSampleSize = 8; constexpr SkScalar kComplexityThreshold = 0.25; #endif -static void compute_complexity(const SkPathView& path, SkScalar& avgLength, SkScalar& complexity) { - int n = path.fPoints.count(); - if (n < kSampleSize || path.fBounds.isEmpty()) { +static void compute_complexity(const SkPath& path, SkScalar& avgLength, SkScalar& complexity) { + int n = path.countPoints(); + if (n < kSampleSize || path.getBounds().isEmpty()) { // set to invalid value to indicate that we failed to compute avgLength = complexity = -1; return; } SkScalar sumLength = 0; - SkPoint lastPoint = path.fPoints[0]; + SkPoint lastPoint = path.getPoint(0); for(int i = 1; i < kSampleSize; ++i) { - SkPoint point = path.fPoints[i]; + SkPoint point = path.getPoint(i); sumLength += SkPoint::Distance(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; }; - 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 // proportional to this. SkScalar intersections = sk_ieee_float_divide(sqr(n) * sqr(avgLength), diagonalSqr); // 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. 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) return false; #else @@ -650,16 +650,16 @@ static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar co } #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 // bounds/resolution, it indicates that the path is not quite smooth in // the current resolution: the expected number of turning points in // every pixel row/column is significantly greater than zero. Hence // Aanlytic AA is not likely to produce visible quality improvements, // 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 - 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 // intersections because AAA will have too many scan lines. See // skbug.com/8272 @@ -671,7 +671,7 @@ static bool ShouldUseAAA(const SkPathView& path, SkScalar avgLength, SkScalar co #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) { bool containedInClip = clipBounds.contains(ir); 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 (!isInverse && MaskSuperBlitter::CanHandleRect(ir) && !forceRLE) { 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); } else { 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); } -void SkScan::AntiFillPath(const SkPathView& path, const SkRegion& origClip, +void SkScan::AntiFillPath(const SkPath& path, const SkRegion& origClip, SkBlitter* blitter, bool forceRLE) { if (origClip.isEmpty()) { return; } const bool isInverse = path.isInverseFillType(); - SkIRect ir = safeRoundOut(path.fBounds); + SkIRect ir = safeRoundOut(path.getBounds()); if (ir.isEmpty()) { if (isInverse) { blitter->blitRegion(origClip); @@ -802,7 +802,7 @@ void SkScan::AntiFillPath(const SkPathView& path, const SkRegion& origClip, #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()) { 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()) { return; } diff --git a/src/core/SkScan_Hairline.cpp b/src/core/SkScan_Hairline.cpp index 25148661f4..5e0f081845 100644 --- a/src/core/SkScan_Hairline.cpp +++ b/src/core/SkScan_Hairline.cpp @@ -507,7 +507,7 @@ void extend_pts(SkPath::Verb prevVerb, SkPath::Verb nextVerb, SkPoint* pts, int } template -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) { if (path.isEmpty()) { 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 SkIRect ibounds = path.fBounds.roundOut().makeOutset(capOut, capOut); + const SkIRect ibounds = path.getBounds().roundOut().makeOutset(capOut, capOut); if (rclip.quickReject(ibounds)) { 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(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(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(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(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(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(path, clip, blitter, SkScan::AntiHairLineRgn); } diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp index b30b40090a..98a8825bb0 100644 --- a/src/core/SkScan_Path.cpp +++ b/src/core/SkScan_Path.cpp @@ -391,10 +391,8 @@ static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) { return list[0]; } -#include "src/core/SkPathView.h" - // 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) { 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) { walk_simple_edges(&headEdge, blitter, start_y, stop_y); } 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()) { return; } @@ -632,7 +632,7 @@ void SkScan::FillPath(const SkPathView& path, const SkRegion& origClip, SkBlitte // don't reference "origClip" any more, just use clipPtr - SkRect bounds = path.fBounds; + SkRect bounds = path.getBounds(); bool irPreClipped = false; if (!SkRectPriv::MakeLargeS32().contains(bounds)) { 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) { SkRegion rgn(ir); 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); } -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()) { 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. const SkScalar limit = SK_MaxS16 >> 1; 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; } diff --git a/tests/FillPathTest.cpp b/tests/FillPathTest.cpp index 8e6f0acc88..04bcb01fa9 100644 --- a/tests/FillPathTest.cpp +++ b/tests/FillPathTest.cpp @@ -42,7 +42,7 @@ DEF_TEST(FillPathInverse, reporter) { SkIntToScalar(width), 0.0f) .close() .setFillType(SkPathFillType::kInverseWinding); - SkScan::FillPath(path.view(), clip, &blitter); + SkScan::FillPath(path, clip, &blitter); REPORTER_ASSERT(reporter, blitter.m_blitCount == expected_lines); } diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index 3152fa2a97..1f826b9979 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -22,7 +22,6 @@ #include "src/core/SkAutoMalloc.h" #include "src/core/SkGeometry.h" #include "src/core/SkPathPriv.h" -#include "src/core/SkPathView.h" #include "src/core/SkReadBuffer.h" #include "src/core/SkWriteBuffer.h" #include "tests/Test.h" @@ -5658,18 +5657,12 @@ static void test_edger(skiatest::Reporter* r, } SkPathEdgeIter iter(path); - SkPathEdgeIter iter2(path.view()); for (auto v : expected) { auto e = iter.next(); REPORTER_ASSERT(r, e); 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, !iter2.next()); } DEF_TEST(pathedger, r) {