Index: src/gpu/batches/GrAADistanceFieldPathRenderer.cpp |
diff --git a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp |
index ee5fdb8a804f23fc88d88e4c96e8d02542fdb866..edb283644397b8da8fddf768d1e033c53cf1e840 100644 |
--- a/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp |
+++ b/src/gpu/batches/GrAADistanceFieldPathRenderer.cpp |
@@ -84,10 +84,9 @@ GrAADistanceFieldPathRenderer::~GrAADistanceFieldPathRenderer() { |
bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const { |
// TODO: Support inverse fill |
- // TODO: Support strokes |
if (!args.fShaderCaps->shaderDerivativeSupport() || !args.fAntiAlias || |
- args.fPath->isInverseFillType() || args.fPath->isVolatile() || |
- !args.fStroke->isFillStyle()) { |
+ SkStrokeRec::kHairline_Style == args.fStroke->getStyle() || |
+ args.fPath->isInverseFillType() || args.fPath->isVolatile()) { |
return false; |
} |
@@ -96,12 +95,18 @@ bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c |
return false; |
} |
- // only support paths smaller than 64x64, scaled to less than 256x256 |
+ // only support paths smaller than kMediumMIP by kMediumMIP, |
+ // scaled to less than 2.0f*kLargeMIP by 2.0f*kLargeMIP |
// the goal is to accelerate rendering of lots of small paths that may be scaling |
SkScalar maxScale = args.fViewMatrix->getMaxScale(); |
const SkRect& bounds = args.fPath->getBounds(); |
SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); |
robertphillips
2015/11/19 19:03:28
// Outset by half the stroke width when stroking
?
jvanverth1
2015/11/19 20:33:23
Done.
|
- return maxDim < 64.f && maxDim * maxScale < 256.f; |
+ if (SkStrokeRec::kStroke_Style == args.fStroke->getStyle() || |
+ SkStrokeRec::kStrokeAndFill_Style == args.fStroke->getStyle()) { |
+ maxDim += args.fStroke->getWidth()*0.5f; |
+ } |
+ |
+ return maxDim < kMediumMIP && maxDim * maxScale < 2.0f*kLargeMIP; |
} |
//////////////////////////////////////////////////////////////////////////////// |
@@ -120,6 +125,7 @@ public: |
struct Geometry { |
Geometry(const SkStrokeRec& stroke) : fStroke(stroke) {} |
SkPath fPath; |
robertphillips
2015/11/19 19:03:28
// The unique ID of the path involved in this draw
jvanverth1
2015/11/19 20:33:23
Done.
|
+ uint32_t fGenID; |
SkStrokeRec fStroke; |
bool fAntiAlias; |
PathData* fPathData; |
@@ -225,8 +231,7 @@ private: |
} |
// check to see if path is cached |
- // TODO: handle stroked vs. filled version of same path |
- PathData::Key key = { args.fPath.getGenerationID(), desiredDimension }; |
+ PathData::Key key(args.fGenID, desiredDimension, args.fStroke); |
args.fPathData = fPathCache->find(key); |
if (nullptr == args.fPathData || !atlas->hasID(args.fPathData->fID)) { |
// Remove the stale cache entry |
@@ -244,6 +249,7 @@ private: |
atlas, |
args.fPathData, |
args.fPath, |
+ args.fGenID, |
args.fStroke, |
args.fAntiAlias, |
desiredDimension, |
@@ -301,8 +307,9 @@ private: |
GrBatchAtlas* atlas, |
PathData* pathData, |
const SkPath& path, |
- const SkStrokeRec& |
- stroke, bool antiAlias, |
+ uint32_t genID, |
+ const SkStrokeRec& stroke, |
+ bool antiAlias, |
uint32_t dimension, |
SkScalar scale) { |
const SkRect& bounds = path.getBounds(); |
@@ -333,41 +340,25 @@ private: |
drawMatrix.postTranslate(kAntiAliasPad, kAntiAliasPad); |
// setup bitmap backing |
- // Now translate so the bound's UL corner is at the origin |
- drawMatrix.postTranslate(-devPathBounds.fLeft * SK_Scalar1, |
- -devPathBounds.fTop * SK_Scalar1); |
- SkIRect pathBounds = SkIRect::MakeWH(devPathBounds.width(), |
- devPathBounds.height()); |
- |
+ SkASSERT(devPathBounds.fLeft == 0); |
+ SkASSERT(devPathBounds.fTop == 0); |
SkAutoPixmapStorage dst; |
- if (!dst.tryAlloc(SkImageInfo::MakeA8(pathBounds.width(), |
- pathBounds.height()))) { |
+ if (!dst.tryAlloc(SkImageInfo::MakeA8(devPathBounds.width(), |
+ devPathBounds.height()))) { |
return false; |
} |
sk_bzero(dst.writable_addr(), dst.getSafeSize()); |
// rasterize path |
SkPaint paint; |
- if (stroke.isHairlineStyle()) { |
- paint.setStyle(SkPaint::kStroke_Style); |
- paint.setStrokeWidth(SK_Scalar1); |
- } else { |
- if (stroke.isFillStyle()) { |
- paint.setStyle(SkPaint::kFill_Style); |
- } else { |
- paint.setStyle(SkPaint::kStroke_Style); |
- paint.setStrokeJoin(stroke.getJoin()); |
- paint.setStrokeCap(stroke.getCap()); |
- paint.setStrokeWidth(stroke.getWidth()); |
- } |
- } |
+ paint.setStyle(SkPaint::kFill_Style); |
paint.setAntiAlias(antiAlias); |
SkDraw draw; |
sk_bzero(&draw, sizeof(draw)); |
SkRasterClip rasterClip; |
- rasterClip.setRect(pathBounds); |
+ rasterClip.setRect(devPathBounds); |
draw.fRC = &rasterClip; |
draw.fClip = &rasterClip.bwRgn(); |
draw.fMatrix = &drawMatrix; |
@@ -403,8 +394,7 @@ private: |
} |
// add to cache |
- pathData->fKey.fGenID = path.getGenerationID(); |
- pathData->fKey.fDimension = dimension; |
+ pathData->fKey = PathData::Key(genID, dimension, stroke); |
pathData->fScale = scale; |
pathData->fID = id; |
// change the scaled rect to match the size of the inset distance field |
@@ -543,9 +533,16 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) { |
} |
AADistanceFieldPathBatch::Geometry geometry(*args.fStroke); |
- geometry.fPath = *args.fPath; |
+ if (SkStrokeRec::kFill_Style == args.fStroke->getStyle()) { |
+ geometry.fPath = *args.fPath; |
+ } else { |
robertphillips
2015/11/19 19:03:28
Do we need 'newPath'? Can't we pass "&geometry.fPa
jvanverth1
2015/11/19 20:33:23
Done.
|
+ SkPath newPath; |
+ args.fStroke->applyToPath(&newPath, *args.fPath); |
+ geometry.fPath = newPath; |
+ } |
geometry.fAntiAlias = args.fAntiAlias; |
robertphillips
2015/11/19 19:03:28
// Note: this is the generation ID of the _origina
jvanverth1
2015/11/19 20:33:23
Done.
|
- |
+ geometry.fGenID = args.fPath->getGenerationID(); |
+ |
SkAutoTUnref<GrDrawBatch> batch(AADistanceFieldPathBatch::Create(geometry, args.fColor, |
*args.fViewMatrix, fAtlas, |
&fPathCache, &fPathList)); |