Index: src/gpu/batches/GrTessellatingPathRenderer.cpp |
diff --git a/src/gpu/batches/GrTessellatingPathRenderer.cpp b/src/gpu/batches/GrTessellatingPathRenderer.cpp |
index d2cfb6e9cba59e12fbd5f2084cb294982fe5491a..2c8520b28aeb9764ad2d603fb417af8ca9487ae6 100644 |
--- a/src/gpu/batches/GrTessellatingPathRenderer.cpp |
+++ b/src/gpu/batches/GrTessellatingPathRenderer.cpp |
@@ -105,10 +105,9 @@ |
bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { |
// This path renderer can draw all fill styles, all stroke styles except hairlines, but does |
// not do antialiasing. It can do convex and concave paths, but we'll leave the convex ones to |
- // simpler algorithms. Similary, we skip the non-hairlines that can be treated as hairline. |
- // An arbitrary path effect could produce a hairline result so we pass on those. |
- return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr) && |
- !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPath->isConvex(); |
+ // simpler algorithms. |
+ return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, nullptr) && |
+ !args.fAntiAlias && !args.fPath->isConvex(); |
} |
class TessellatingPathBatch : public GrVertexBatch { |
@@ -117,10 +116,10 @@ |
static GrDrawBatch* Create(const GrColor& color, |
const SkPath& path, |
- const GrStyle& style, |
+ const GrStrokeInfo& stroke, |
const SkMatrix& viewMatrix, |
SkRect clipBounds) { |
- return new TessellatingPathBatch(color, path, style, viewMatrix, clipBounds); |
+ return new TessellatingPathBatch(color, path, stroke, viewMatrix, clipBounds); |
} |
const char* name() const override { return "TessellatingPathBatch"; } |
@@ -143,50 +142,47 @@ |
} |
void draw(Target* target, const GrGeometryProcessor* gp) const { |
- GrResourceProvider* rp = target->resourceProvider(); |
- SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; |
- SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMatrix, |
- fPath.getBounds()); |
- |
- SkScalar styleScale = SK_Scalar1; |
- if (fStyle.applies()) { |
- styleScale = GrStyle::MatrixToScaleFactor(fViewMatrix); |
- } |
- |
// construct a cache key from the path's genID and the view matrix |
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
GrUniqueKey key; |
- int clipBoundsCnt = |
+ int clipBoundsSize32 = |
fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0; |
- int styleDataCnt = GrStyle::KeySize(fStyle, GrStyle::Apply::kPathEffectAndStrokeRec); |
- if (styleDataCnt >= 0) { |
- GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsCnt + styleDataCnt); |
- builder[0] = fPath.getGenerationID(); |
- builder[1] = fPath.getFillType(); |
- // For inverse fills, the tessellation is dependent on clip bounds. |
- if (fPath.isInverseFillType()) { |
- memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); |
- } |
- if (styleDataCnt) { |
- GrStyle::WriteKey(&builder[2 + clipBoundsCnt], fStyle, |
- GrStyle::Apply::kPathEffectAndStrokeRec, styleScale); |
- } |
- builder.finish(); |
- SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrBuffer>(key)); |
- int actualCount; |
- if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { |
- this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCount); |
+ int strokeDataSize32 = fStroke.computeUniqueKeyFragmentData32Cnt(); |
+ GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32 + strokeDataSize32); |
+ builder[0] = fPath.getGenerationID(); |
+ builder[1] = fPath.getFillType(); |
+ // For inverse fills, the tessellation is dependent on clip bounds. |
+ if (fPath.isInverseFillType()) { |
+ memcpy(&builder[2], &fClipBounds, sizeof(fClipBounds)); |
+ } |
+ fStroke.asUniqueKeyFragment(&builder[2 + clipBoundsSize32]); |
+ builder.finish(); |
+ GrResourceProvider* rp = target->resourceProvider(); |
+ SkAutoTUnref<GrBuffer> cachedVertexBuffer(rp->findAndRefTByUniqueKey<GrBuffer>(key)); |
+ int actualCount; |
+ SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance; |
+ SkScalar tol = GrPathUtils::scaleToleranceToSrc( |
+ screenSpaceTol, fViewMatrix, fPath.getBounds()); |
+ if (cache_match(cachedVertexBuffer.get(), tol, &actualCount)) { |
+ this->drawVertices(target, gp, cachedVertexBuffer.get(), 0, actualCount); |
+ return; |
+ } |
+ |
+ SkPath path; |
+ GrStrokeInfo stroke(fStroke); |
+ if (stroke.isDashed()) { |
+ if (!stroke.applyDashToPath(&path, &stroke, fPath)) { |
return; |
} |
- } |
- |
- SkPath path; |
- if (fStyle.applies()) { |
- SkStrokeRec::InitStyle fill; |
- SkAssertResult(fStyle.applyToPath(&path, &fill, fPath, styleScale)); |
- SkASSERT(SkStrokeRec::kFill_InitStyle == fill); |
} else { |
path = fPath; |
+ } |
+ if (!stroke.isFillStyle()) { |
+ stroke.setResScale(SkScalarAbs(fViewMatrix.getMaxScale())); |
+ if (!stroke.applyToPath(&path, path)) { |
+ return; |
+ } |
+ stroke.setFillStyle(); |
} |
bool isLinear; |
bool canMapVB = GrCaps::kNone_MapFlags != target->caps().mapBufferFlags(); |
@@ -196,7 +192,7 @@ |
return; |
} |
this->drawVertices(target, gp, allocator.vertexBuffer(), 0, count); |
- if (!fPath.isVolatile() && styleDataCnt >= 0) { |
+ if (!fPath.isVolatile()) { |
TessInfo info; |
info.fTolerance = isLinear ? 0 : tol; |
info.fCount = count; |
@@ -244,13 +240,13 @@ |
TessellatingPathBatch(const GrColor& color, |
const SkPath& path, |
- const GrStyle& style, |
+ const GrStrokeInfo& stroke, |
const SkMatrix& viewMatrix, |
const SkRect& clipBounds) |
: INHERITED(ClassID()) |
, fColor(color) |
, fPath(path) |
- , fStyle(style) |
+ , fStroke(stroke) |
, fViewMatrix(viewMatrix) { |
const SkRect& pathBounds = path.getBounds(); |
fClipBounds = clipBounds; |
@@ -262,13 +258,14 @@ |
} else { |
fBounds = path.getBounds(); |
} |
- style.adjustBounds(&fBounds, fBounds); |
+ SkScalar radius = stroke.getInflationRadius(); |
+ fBounds.outset(radius, radius); |
viewMatrix.mapRect(&fBounds); |
} |
GrColor fColor; |
SkPath fPath; |
- GrStyle fStyle; |
+ GrStrokeInfo fStroke; |
SkMatrix fViewMatrix; |
SkRect fClipBounds; // in source space |
GrXPOverridesForBatch fPipelineInfo; |
@@ -294,7 +291,7 @@ |
} |
vmi.mapRect(&clipBounds); |
SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath, |
- *args.fStyle, *args.fViewMatrix, |
+ *args.fStroke, *args.fViewMatrix, |
clipBounds)); |
args.fTarget->drawBatch(*args.fPipelineBuilder, batch); |
@@ -316,11 +313,8 @@ |
SkFAIL("Cannot invert matrix\n"); |
} |
vmi.mapRect(&clipBounds); |
- GrStyle style; |
- do { |
- GrTest::TestStyle(random, &style); |
- } while (style.strokeRec().isHairlineStyle()); |
- return TessellatingPathBatch::Create(color, path, style, viewMatrix, clipBounds); |
+ GrStrokeInfo strokeInfo = GrTest::TestStrokeInfo(random); |
+ return TessellatingPathBatch::Create(color, path, strokeInfo, viewMatrix, clipBounds); |
} |
#endif |