bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target, const GrPipelineBuilder* pipelineBuilder, const SkMatrix& viewMatrix, const SkPath& path, const GrStrokeInfo& stroke, bool antiAlias) const { // TODO: Support inverse fill // TODO: Support strokes if (!target->caps()->shaderCaps()->shaderDerivativeSupport() || !antiAlias || path.isInverseFillType() || path.isVolatile() || !stroke.isFillStyle()) { return false; } // currently don't support perspective if (viewMatrix.hasPerspective()) { return false; } // only support paths smaller than 64x64, scaled to less than 256x256 // the goal is to accelerate rendering of lots of small paths that may be scaling SkScalar maxScale = viewMatrix.getMaxScale(); const SkRect& bounds = path.getBounds(); SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); return maxDim < 64.f && maxDim * maxScale < 256.f; }
TessellatingPathBatch(const GrColor& color, const SkPath& path, const GrStrokeInfo& stroke, const SkMatrix& viewMatrix, const SkRect& clipBounds) : INHERITED(ClassID()) , fColor(color) , fPath(path) , fStroke(stroke) , fViewMatrix(viewMatrix) { const SkRect& pathBounds = path.getBounds(); fClipBounds = clipBounds; // Because the clip bounds are used to add a contour for inverse fills, they must also // include the path bounds. fClipBounds.join(pathBounds); if (path.isInverseFillType()) { fBounds = fClipBounds; } else { 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); }
bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target, const GrPipelineBuilder*, const SkMatrix& viewMatrix, const SkPath& path, const GrStrokeInfo& stroke, bool antiAlias) const { return (target->caps()->shaderCaps()->shaderDerivativeSupport() && antiAlias && stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex()); }
bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target, const GrPipelineBuilder* pipelineBuilder, const SkMatrix& viewMatrix, const SkPath& path, const GrStrokeInfo& stroke, bool antiAlias) const { // this class can draw any path with any fill but doesn't do any anti-aliasing. return !antiAlias && (stroke.isFillStyle() || IsStrokeHairlineOrEquivalent(stroke, viewMatrix, NULL)); }
bool GrAALinearizingConvexPathRenderer::onDrawPath(GrDrawTarget* target, GrPipelineBuilder* pipelineBuilder, GrColor color, const SkMatrix& vm, const SkPath& path, const GrStrokeInfo& stroke, bool antiAlias) { if (path.isEmpty()) { return true; } AAFlatteningConvexPathBatch::Geometry geometry; geometry.fColor = color; geometry.fViewMatrix = vm; geometry.fPath = path; geometry.fStrokeWidth = stroke.isFillStyle() ? -1.0f : stroke.getWidth(); geometry.fJoin = stroke.isFillStyle() ? SkPaint::Join::kMiter_Join : stroke.getJoin(); geometry.fMiterLimit = stroke.getMiter(); SkAutoTUnref<GrBatch> batch(AAFlatteningConvexPathBatch::Create(geometry)); target->drawBatch(pipelineBuilder, batch); return true; }