Revert of Make AALinearizingConvexPathRenderer able to handle stroke and fill (patchset #7 id:120001 of https://codereview.chromium.org/2301353004/ )
Reason for revert: Image quality issues on Android devices Original issue's description: > Make AALinearizingConvexPathRenderer able to handle stroke and fill > > This is intended to catch stroke-and-fill convex paths with potentially small stroke widths (e.g., .1). > > It does have the disconcerting side effect of changing bevel-joined stroke-and-filled degenerate-single-line-rects into plain rects (w/o triangular end-caps). > > GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2301353004 > > Committed: https://skia.googlesource.com/skia/+/522bcd99fa65a8abd130880f59b500cf367d0845 TBR=ethannicholas@google.com,jvanverth@google.com # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Review-Url: https://codereview.chromium.org/2318183002
This commit is contained in:
parent
b393a49e5f
commit
7a00e8bc98
@ -32,17 +32,11 @@ static const SkScalar kRoundCapThreshold = 0.8f;
|
||||
// dot product above which we consider two adjacent curves to be part of the "same" curve
|
||||
static const SkScalar kCurveConnectionThreshold = 0.8f;
|
||||
|
||||
static bool intersect(const SkPoint& p0, const SkPoint& n0,
|
||||
const SkPoint& p1, const SkPoint& n1,
|
||||
SkScalar* t) {
|
||||
static SkScalar intersect(const SkPoint& p0, const SkPoint& n0,
|
||||
const SkPoint& p1, const SkPoint& n1) {
|
||||
const SkPoint v = p1 - p0;
|
||||
SkScalar perpDot = n0.fX * n1.fY - n0.fY * n1.fX;
|
||||
if (SkScalarNearlyZero(perpDot)) {
|
||||
return false;
|
||||
}
|
||||
*t = (v.fX * n1.fY - v.fY * n1.fX) / perpDot;
|
||||
SkASSERT(SkScalarIsFinite(*t));
|
||||
return true;
|
||||
return (v.fX * n1.fY - v.fY * n1.fX) / perpDot;
|
||||
}
|
||||
|
||||
// This is a special case version of intersect where we have the vector
|
||||
@ -224,44 +218,7 @@ bool GrAAConvexTessellator::tessellate(const SkMatrix& m, const SkPath& path) {
|
||||
|
||||
SkScalar coverage = 1.0f;
|
||||
SkScalar scaleFactor = 0.0f;
|
||||
|
||||
if (SkStrokeRec::kStrokeAndFill_Style == fStyle) {
|
||||
SkASSERT(m.isSimilarity());
|
||||
scaleFactor = m.getMaxScale(); // x and y scale are the same
|
||||
SkScalar effectiveStrokeWidth = scaleFactor * fStrokeWidth;
|
||||
Ring outerStrokeAndAARing;
|
||||
this->createOuterRing(fInitialRing,
|
||||
effectiveStrokeWidth / 2 + kAntialiasingRadius, 0.0,
|
||||
&outerStrokeAndAARing);
|
||||
|
||||
// discard all the triangles added between the originating ring and the new outer ring
|
||||
fIndices.rewind();
|
||||
|
||||
outerStrokeAndAARing.init(*this);
|
||||
|
||||
outerStrokeAndAARing.makeOriginalRing();
|
||||
|
||||
// Add the outer stroke ring's normals to the originating ring's normals
|
||||
// so it can also act as an originating ring
|
||||
fNorms.setReserve(fNorms.count() + outerStrokeAndAARing.numPts());
|
||||
for (int i = 0; i < outerStrokeAndAARing.numPts(); ++i) {
|
||||
fNorms.push(outerStrokeAndAARing.norm(i));
|
||||
}
|
||||
|
||||
// the bisectors are only needed for the computation of the outer ring
|
||||
fBisectors.rewind();
|
||||
|
||||
Ring* insetAARing;
|
||||
this->createInsetRings(outerStrokeAndAARing,
|
||||
0.0f, 0.0f, 2*kAntialiasingRadius, 1.0f,
|
||||
&insetAARing);
|
||||
|
||||
SkDEBUGCODE(this->validate();)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SkStrokeRec::kStroke_Style == fStyle) {
|
||||
SkASSERT(fStrokeWidth >= 0.0f);
|
||||
if (fStrokeWidth >= 0.0f) {
|
||||
SkASSERT(m.isSimilarity());
|
||||
scaleFactor = m.getMaxScale(); // x and y scale are the same
|
||||
SkScalar effectiveStrokeWidth = scaleFactor * fStrokeWidth;
|
||||
@ -278,16 +235,15 @@ bool GrAAConvexTessellator::tessellate(const SkMatrix& m, const SkPath& path) {
|
||||
|
||||
// the bisectors are only needed for the computation of the outer ring
|
||||
fBisectors.rewind();
|
||||
if (SkStrokeRec::kStroke_Style == fStyle && fInitialRing.numPts() > 2) {
|
||||
SkASSERT(fStrokeWidth >= 0.0f);
|
||||
if (fStrokeWidth >= 0.0f && fInitialRing.numPts() > 2) {
|
||||
SkScalar effectiveStrokeWidth = scaleFactor * fStrokeWidth;
|
||||
Ring* insetStrokeRing;
|
||||
SkScalar strokeDepth = effectiveStrokeWidth / 2 - kAntialiasingRadius;
|
||||
if (this->createInsetRings(fInitialRing, 0.0f, coverage, strokeDepth, coverage,
|
||||
&insetStrokeRing)) {
|
||||
&insetStrokeRing)) {
|
||||
Ring* insetAARing;
|
||||
this->createInsetRings(*insetStrokeRing, strokeDepth, coverage, strokeDepth +
|
||||
kAntialiasingRadius * 2, 0.0f, &insetAARing);
|
||||
kAntialiasingRadius * 2, 0.0f, &insetAARing);
|
||||
}
|
||||
} else {
|
||||
Ring* insetAARing;
|
||||
@ -434,7 +390,7 @@ bool GrAAConvexTessellator::extractFromPath(const SkMatrix& m, const SkPath& pat
|
||||
this->computeBisectors();
|
||||
} else if (this->numPts() == 2) {
|
||||
// We've got two points, so we're degenerate.
|
||||
if (fStyle == SkStrokeRec::kFill_Style) {
|
||||
if (fStrokeWidth < 0.0f) {
|
||||
// it's a fill, so we don't need to worry about degenerate paths
|
||||
return false;
|
||||
}
|
||||
@ -630,7 +586,7 @@ void GrAAConvexTessellator::createOuterRing(const Ring& previousRing, SkScalar o
|
||||
// Something went wrong in the creation of the next ring. If we're filling the shape, just go ahead
|
||||
// and fan it.
|
||||
void GrAAConvexTessellator::terminate(const Ring& ring) {
|
||||
if (fStyle != SkStrokeRec::kStroke_Style) {
|
||||
if (fStrokeWidth < 0.0f) {
|
||||
this->fanRing(ring);
|
||||
}
|
||||
}
|
||||
@ -660,14 +616,8 @@ bool GrAAConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing
|
||||
|
||||
for (int cur = 0; cur < lastRing.numPts(); ++cur) {
|
||||
int next = (cur + 1) % lastRing.numPts();
|
||||
|
||||
SkScalar t;
|
||||
bool result = intersect(this->point(lastRing.index(cur)), lastRing.bisector(cur),
|
||||
this->point(lastRing.index(next)), lastRing.bisector(next),
|
||||
&t);
|
||||
if (!result) {
|
||||
continue;
|
||||
}
|
||||
SkScalar t = intersect(this->point(lastRing.index(cur)), lastRing.bisector(cur),
|
||||
this->point(lastRing.index(next)), lastRing.bisector(next));
|
||||
SkScalar dist = -t * lastRing.norm(cur).dot(lastRing.bisector(cur));
|
||||
|
||||
if (minDist > dist) {
|
||||
@ -795,8 +745,8 @@ bool GrAAConvexTessellator::createInsetRing(const Ring& lastRing, Ring* nextRing
|
||||
this->addTri(lastRing.index(i), dst[next], dst[i]);
|
||||
}
|
||||
|
||||
if (done && fStyle != SkStrokeRec::kStroke_Style) {
|
||||
// fill or stroke-and-fill
|
||||
if (done && fStrokeWidth < 0.0f) {
|
||||
// fill
|
||||
this->fanRing(*nextRing);
|
||||
}
|
||||
|
||||
@ -910,7 +860,7 @@ void GrAAConvexTessellator::lineTo(SkPoint p, CurveState curve) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
SkScalar initialRingCoverage = (SkStrokeRec::kFill_Style == fStyle) ? 0.5f : 1.0f;
|
||||
SkScalar initialRingCoverage = fStrokeWidth < 0.0f ? 0.5f : 1.0f;
|
||||
this->addPt(p, 0.0f, initialRingCoverage, false, curve);
|
||||
if (this->numPts() > 1) {
|
||||
*fNorms.push() = fPts.top() - fPts[fPts.count()-2];
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "SkPaint.h"
|
||||
#include "SkPoint.h"
|
||||
#include "SkScalar.h"
|
||||
#include "SkStrokeRec.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
class SkCanvas;
|
||||
@ -32,13 +31,11 @@ class GrAAConvexTessellator;
|
||||
// computeDepthFromEdge requests.
|
||||
class GrAAConvexTessellator {
|
||||
public:
|
||||
GrAAConvexTessellator(SkStrokeRec::Style style = SkStrokeRec::kFill_Style,
|
||||
SkScalar strokeWidth = -1.0f,
|
||||
GrAAConvexTessellator(SkScalar strokeWidth = -1.0f,
|
||||
SkPaint::Join join = SkPaint::Join::kBevel_Join,
|
||||
SkScalar miterLimit = 0.0f)
|
||||
: fSide(SkPoint::kOn_Side)
|
||||
, fStrokeWidth(strokeWidth)
|
||||
, fStyle(style)
|
||||
, fJoin(join)
|
||||
, fMiterLimit(miterLimit) {
|
||||
}
|
||||
@ -139,13 +136,6 @@ private:
|
||||
pt->fOrigEdgeId = origEdgeId;
|
||||
}
|
||||
|
||||
// Upgrade this ring so that it can behave like an originating ring
|
||||
void makeOriginalRing() {
|
||||
for (int i = 0; i < fPts.count(); ++i) {
|
||||
fPts[i].fOrigEdgeId = fPts[i].fIndex;
|
||||
}
|
||||
}
|
||||
|
||||
// init should be called after all the indices have been added (via addIdx)
|
||||
void init(const GrAAConvexTessellator& tess);
|
||||
void init(const SkTDArray<SkVector>& norms, const SkTDArray<SkVector>& bisectors);
|
||||
@ -277,9 +267,8 @@ private:
|
||||
#endif
|
||||
CandidateVerts fCandidateVerts;
|
||||
|
||||
// the stroke width is only used for stroke or stroke-and-fill styles
|
||||
// < 0 means filling rather than stroking
|
||||
SkScalar fStrokeWidth;
|
||||
SkStrokeRec::Style fStyle;
|
||||
|
||||
SkPaint::Join fJoin;
|
||||
|
||||
|
@ -50,17 +50,12 @@ bool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& arg
|
||||
return false;
|
||||
}
|
||||
const SkStrokeRec& stroke = args.fShape->style().strokeRec();
|
||||
|
||||
if (stroke.getStyle() == SkStrokeRec::kStroke_Style ||
|
||||
stroke.getStyle() == SkStrokeRec::kStrokeAndFill_Style) {
|
||||
if (stroke.getStyle() == SkStrokeRec::kStroke_Style) {
|
||||
if (!args.fViewMatrix->isSimilarity()) {
|
||||
return false;
|
||||
}
|
||||
SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth();
|
||||
if (strokeWidth < 1.0f && stroke.getStyle() == SkStrokeRec::kStroke_Style) {
|
||||
return false;
|
||||
}
|
||||
return strokeWidth <= kMaxStrokeWidth &&
|
||||
return strokeWidth >= 1.0f && strokeWidth <= kMaxStrokeWidth &&
|
||||
args.fShape->knownToBeClosed() &&
|
||||
stroke.getJoin() != SkPaint::Join::kRound_Join;
|
||||
}
|
||||
@ -131,11 +126,9 @@ public:
|
||||
const SkMatrix& viewMatrix,
|
||||
const SkPath& path,
|
||||
SkScalar strokeWidth,
|
||||
SkStrokeRec::Style style,
|
||||
SkPaint::Join join,
|
||||
SkScalar miterLimit) : INHERITED(ClassID()) {
|
||||
fGeoData.emplace_back(Geometry{ color, viewMatrix, path,
|
||||
strokeWidth, style, join, miterLimit });
|
||||
fGeoData.emplace_back(Geometry{color, viewMatrix, path, strokeWidth, join, miterLimit});
|
||||
|
||||
// compute bounds
|
||||
SkRect bounds = path.getBounds();
|
||||
@ -236,8 +229,7 @@ private:
|
||||
uint16_t* indices = (uint16_t*) sk_malloc_throw(maxIndices * sizeof(uint16_t));
|
||||
for (int i = 0; i < instanceCount; i++) {
|
||||
const Geometry& args = fGeoData[i];
|
||||
GrAAConvexTessellator tess(args.fStyle, args.fStrokeWidth,
|
||||
args.fJoin, args.fMiterLimit);
|
||||
GrAAConvexTessellator tess(args.fStrokeWidth, args.fJoin, args.fMiterLimit);
|
||||
|
||||
if (!tess.tessellate(args.fViewMatrix, args.fPath)) {
|
||||
continue;
|
||||
@ -317,7 +309,6 @@ private:
|
||||
SkMatrix fViewMatrix;
|
||||
SkPath fPath;
|
||||
SkScalar fStrokeWidth;
|
||||
SkStrokeRec::Style fStyle;
|
||||
SkPaint::Join fJoin;
|
||||
SkScalar fMiterLimit;
|
||||
};
|
||||
@ -333,7 +324,6 @@ bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
|
||||
"GrAALinearizingConvexPathRenderer::onDrawPath");
|
||||
SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
|
||||
SkASSERT(!args.fShape->isEmpty());
|
||||
SkASSERT(!args.fShape->style().pathEffect());
|
||||
|
||||
SkPath path;
|
||||
args.fShape->asPath(&path);
|
||||
@ -345,9 +335,8 @@ bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
|
||||
|
||||
SkAutoTUnref<GrDrawBatch> batch(new AAFlatteningConvexPathBatch(args.fPaint->getColor(),
|
||||
*args.fViewMatrix,
|
||||
path, strokeWidth,
|
||||
stroke.getStyle(),
|
||||
join, miterLimit));
|
||||
path, strokeWidth, join,
|
||||
miterLimit));
|
||||
|
||||
GrPipelineBuilder pipelineBuilder(*args.fPaint);
|
||||
pipelineBuilder.setUserStencil(args.fUserStencilSettings);
|
||||
@ -365,29 +354,10 @@ DRAW_BATCH_TEST_DEFINE(AAFlatteningConvexPathBatch) {
|
||||
GrColor color = GrRandomColor(random);
|
||||
SkMatrix viewMatrix = GrTest::TestMatrixInvertible(random);
|
||||
SkPath path = GrTest::TestPathConvex(random);
|
||||
|
||||
SkStrokeRec::Style styles[3] = { SkStrokeRec::kFill_Style,
|
||||
SkStrokeRec::kStroke_Style,
|
||||
SkStrokeRec::kStrokeAndFill_Style };
|
||||
|
||||
SkStrokeRec::Style style = styles[random->nextU() % 3];
|
||||
|
||||
SkScalar strokeWidth = -1.f;
|
||||
SkScalar strokeWidth = random->nextBool() ? -1.f : 2.f;
|
||||
SkPaint::Join join = SkPaint::kMiter_Join;
|
||||
SkScalar miterLimit = 0.5f;
|
||||
|
||||
if (SkStrokeRec::kFill_Style != style) {
|
||||
strokeWidth = random->nextRangeF(1.0f, 10.0f);
|
||||
if (random->nextBool()) {
|
||||
join = SkPaint::kMiter_Join;
|
||||
} else {
|
||||
join = SkPaint::kBevel_Join;
|
||||
}
|
||||
miterLimit = random->nextRangeF(0.5f, 2.0f);
|
||||
}
|
||||
|
||||
return new AAFlatteningConvexPathBatch(color, viewMatrix, path, strokeWidth,
|
||||
style, join, miterLimit);
|
||||
return new AAFlatteningConvexPathBatch(color, viewMatrix, path, strokeWidth, join, miterLimit);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user