Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Unified Diff: src/gpu/GrTessellatingPathRenderer.cpp

Issue 1275553002: Implement caching of stroked paths in the tessellating path renderer. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Use IsStrokeHairlineOrEquivalent() instead of stroke->isHairline() Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/gpu/GrTessellatingPathRenderer.cpp
diff --git a/src/gpu/GrTessellatingPathRenderer.cpp b/src/gpu/GrTessellatingPathRenderer.cpp
index 282efe251666a46ac42b04424e58c76d46c3b447..ee8ee23fa1984806eed06a706778bbc43405c544 100644
--- a/src/gpu/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/GrTessellatingPathRenderer.cpp
@@ -1384,9 +1384,11 @@ private:
} // namespace
bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- // This path renderer can draw all fill styles, but does not do antialiasing. It can do convex
- // and concave paths, but we'll leave the convex ones to simpler algorithms.
- return args.fStroke->isFillStyle() && !args.fAntiAlias && !args.fPath->isConvex();
+ // 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.
+ return !IsStrokeHairlineOrEquivalent(*args.fStroke, *args.fViewMatrix, NULL) &&
+ !args.fAntiAlias && !args.fPath->isConvex();
}
class TessellatingPathBatch : public GrBatch {
@@ -1394,9 +1396,10 @@ public:
static GrBatch* Create(const GrColor& color,
const SkPath& path,
+ const GrStrokeInfo& stroke,
const SkMatrix& viewMatrix,
SkRect clipBounds) {
- return SkNEW_ARGS(TessellatingPathBatch, (color, path, viewMatrix, clipBounds));
+ return SkNEW_ARGS(TessellatingPathBatch, (color, path, stroke, viewMatrix, clipBounds));
}
const char* name() const override { return "TessellatingPathBatch"; }
@@ -1421,7 +1424,23 @@ public:
int tessellate(GrUniqueKey* key,
GrResourceProvider* resourceProvider,
SkAutoTUnref<GrVertexBuffer>& vertexBuffer) {
- SkRect pathBounds = fPath.getBounds();
+ SkPath path;
+ GrStrokeInfo stroke(fStroke);
+ if (stroke.isDashed()) {
+ if (!stroke.applyDashToPath(&path, &stroke, fPath)) {
+ return 0;
+ }
+ } else {
+ path = fPath;
+ }
+ if (!stroke.isFillStyle()) {
+ stroke.setResScale(SkScalarAbs(fViewMatrix.getMaxScale()));
+ if (!stroke.applyToPath(&path, path)) {
+ return 0;
+ }
+ stroke.setFillStyle();
+ }
+ SkRect pathBounds = path.getBounds();
Comparator c;
if (pathBounds.width() > pathBounds.height()) {
c.sweep_lt = sweep_lt_horiz;
@@ -1433,7 +1452,7 @@ public:
SkScalar screenSpaceTol = GrPathUtils::kDefaultTolerance;
SkScalar tol = GrPathUtils::scaleToleranceToSrc(screenSpaceTol, fViewMatrix, pathBounds);
int contourCnt;
- int maxPts = GrPathUtils::worstCasePointCount(fPath, &contourCnt, tol);
+ int maxPts = GrPathUtils::worstCasePointCount(path, &contourCnt, tol);
if (maxPts <= 0) {
return 0;
}
@@ -1441,7 +1460,7 @@ public:
SkDebugf("Path not rendered, too many verts (%d)\n", maxPts);
return 0;
}
- SkPath::FillType fillType = fPath.getFillType();
+ SkPath::FillType fillType = path.getFillType();
if (SkPath::IsInverseFillType(fillType)) {
contourCnt++;
}
@@ -1455,7 +1474,7 @@ public:
// connectivity of one Edge per Vertex (will grow for intersections).
SkChunkAlloc alloc(maxPts * (3 * sizeof(Vertex) + sizeof(Edge)));
bool isLinear;
- path_to_contours(fPath, tol, fClipBounds, contours.get(), alloc, &isLinear);
+ path_to_contours(path, tol, fClipBounds, contours.get(), alloc, &isLinear);
Poly* polys;
polys = contours_to_polys(contours.get(), contourCnt, c, alloc);
int count = 0;
@@ -1503,13 +1522,15 @@ public:
GrUniqueKey key;
int clipBoundsSize32 =
fPath.isInverseFillType() ? sizeof(fClipBounds) / sizeof(uint32_t) : 0;
- GrUniqueKey::Builder builder(&key, kDomain, 2 + clipBoundsSize32);
+ 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 = batchTarget->resourceProvider();
SkAutoTUnref<GrVertexBuffer> vertexBuffer(rp->findAndRefTByUniqueKey<GrVertexBuffer>(key));
@@ -1561,20 +1582,33 @@ public:
private:
TessellatingPathBatch(const GrColor& color,
const SkPath& path,
+ const GrStrokeInfo& stroke,
const SkMatrix& viewMatrix,
const SkRect& clipBounds)
: fColor(color)
, fPath(path)
+ , fStroke(stroke)
, fViewMatrix(viewMatrix)
, fClipBounds(clipBounds) {
this->initClassID<TessellatingPathBatch>();
fBounds = path.getBounds();
+ if (!stroke.isFillStyle()) {
+ SkScalar radius = SkScalarHalf(stroke.getWidth());
+ if (stroke.getJoin() == SkPaint::kMiter_Join) {
+ SkScalar scale = stroke.getMiter();
+ if (scale > SK_Scalar1) {
+ radius = SkScalarMul(radius, scale);
+ }
+ }
+ fBounds.outset(radius, radius);
+ }
viewMatrix.mapRect(&fBounds);
}
GrColor fColor;
SkPath fPath;
+ GrStrokeInfo fStroke;
SkMatrix fViewMatrix;
SkRect fClipBounds; // in source space
GrPipelineInfo fPipelineInfo;
@@ -1596,7 +1630,8 @@ bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
}
vmi.mapRect(&clipBounds);
SkAutoTUnref<GrBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath,
- *args.fViewMatrix, clipBounds));
+ *args.fStroke, *args.fViewMatrix,
+ clipBounds));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;
@@ -1617,7 +1652,8 @@ BATCH_TEST_DEFINE(TesselatingPathBatch) {
SkFAIL("Cannot invert matrix\n");
}
vmi.mapRect(&clipBounds);
- return TessellatingPathBatch::Create(color, path, viewMatrix, clipBounds);
+ GrStrokeInfo strokeInfo = GrTest::TestStrokeInfo(random);
+ return TessellatingPathBatch::Create(color, path, strokeInfo, viewMatrix, clipBounds);
}
#endif
« no previous file with comments | « include/gpu/GrTestUtils.h ('k') | src/gpu/GrTestUtils.cpp » ('j') | src/gpu/GrTestUtils.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698