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 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

View File

@ -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 <limits>
#include <tuple>
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.

View File

@ -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;

View File

@ -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();

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 (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,

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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()) {

View File

@ -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:

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 {
// 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;

View File

@ -10,7 +10,6 @@
#include "include/core/SkPathBuilder.h"
#include "include/private/SkIDChangeListener.h"
#include "src/core/SkPathView.h"
static_assert(0 == static_cast<int>(SkPathFillType::kWinding), "fill_type_mismatch");
static_assert(1 == static_cast<int>(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<int>(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);

View File

@ -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<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();
}
SkScan::FillPath(path.view(), clip, &builder);
SkScan::FillPath(path, clip, &builder);
builder.done();
int count = builder.computeRunCount();

View File

@ -11,13 +11,12 @@
#include "include/core/SkRect.h"
#include "include/private/SkFixed.h"
#include "src/core/SkPathView.h"
#include <atomic>
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);
};

View File

@ -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

View File

@ -25,7 +25,7 @@
#include <utility>
#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,

View File

@ -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;
}

View File

@ -507,7 +507,7 @@ void extend_pts(SkPath::Verb prevVerb, SkPath::Verb nextVerb, SkPoint* pts, int
}
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) {
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<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);
}
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);
}
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);
}
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);
}
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);
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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) {