: GrPathRendererChain::kColor_DrawType;
}
+ GrShape shape(path, GrStyle::SimpleFill());
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
canDrawArgs.fViewMatrix = &viewMatrix;
- canDrawArgs.fPath = &path;
- canDrawArgs.fStyle = &GrStyle::SimpleFill();
+ canDrawArgs.fShape = &shape;
canDrawArgs.fAntiAlias = element->isAA();
canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled();
clipPath.toggleInverseFillType();
}
+ GrShape shape(clipPath, GrStyle::SimpleFill());
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
canDrawArgs.fViewMatrix = &viewMatrix;
- canDrawArgs.fPath = &clipPath;
- canDrawArgs.fStyle = &GrStyle::SimpleFill();
+ canDrawArgs.fShape = &shape;
canDrawArgs.fAntiAlias = false;
canDrawArgs.fHasUserStencilSettings = false;
canDrawArgs.fIsStencilBufferMSAA = drawContext->isStencilBufferMultisampled();
viewMatrix, element->getRect());
} else {
if (!clipPath.isEmpty()) {
+ GrShape shape(clipPath, GrStyle::SimpleFill());
if (canRenderDirectToStencil) {
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Make());
args.fClip = &clip;
args.fColor = GrColor_WHITE;
args.fViewMatrix = &viewMatrix;
- args.fPath = &clipPath;
- args.fStyle = &GrStyle::SimpleFill();
+ args.fShape = &shape;
args.fAntiAlias = false;
args.fGammaCorrect = false;
pr->drawPath(args);
args.fDrawContext = drawContext;
args.fClip = &clip;
args.fViewMatrix = &viewMatrix;
- args.fPath = &clipPath;
args.fIsAA = element->isAA();
+ args.fShape = &shape;
pr->stencilPath(args);
}
}
drawContext->drawContextPriv().stencilRect(clip, *pass, useHWAA, viewMatrix,
element->getRect());
} else {
+ GrShape shape(clipPath, GrStyle::SimpleFill());
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Make());
paint.setAntiAlias(element->isAA());
-
GrPathRenderer::DrawPathArgs args;
args.fResourceProvider = context->resourceProvider();
args.fPaint = &paint;
args.fClip = &clip;
args.fColor = GrColor_WHITE;
args.fViewMatrix = &viewMatrix;
- args.fPath = &clipPath;
- args.fStyle = &GrStyle::SimpleFill();
+ args.fShape = &shape;
args.fAntiAlias = false;
args.fGammaCorrect = false;
pr->drawPath(args);
SkPath clipPath;
element->asPath(&clipPath);
clipPath.toggleInverseFillType();
- helper.drawPath(clipPath, GrStyle::SimpleFill(), SkRegion::kReplace_Op,
- element->isAA(), 0x00);
+ GrShape shape(clipPath, GrStyle::SimpleFill());
+ helper.drawShape(shape, SkRegion::kReplace_Op, element->isAA(), 0x00);
continue;
}
} else {
SkPath path;
element->asPath(&path);
- helper.drawPath(path, GrStyle::SimpleFill(), op, element->isAA(), 0xFF);
+ GrShape shape(path, GrStyle::SimpleFill());
+ helper.drawShape(shape, op, element->isAA(), 0xFF);
}
}
useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
: GrPathRendererChain::kColor_DrawType;
+ GrShape shape(path, GrStyle::SimpleFill());
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fShaderCaps = fDrawContext->fDrawingManager->getContext()->caps()->shaderCaps();
canDrawArgs.fViewMatrix = &viewMatrix;
- canDrawArgs.fPath = &path;
- canDrawArgs.fStyle = &GrStyle::SimpleFill();
+ canDrawArgs.fShape = &shape;
canDrawArgs.fAntiAlias = useCoverageAA;
canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
args.fClip = &clip;
args.fColor = GrColor_WHITE;
args.fViewMatrix = &viewMatrix;
- args.fPath = &path;
- args.fStyle = &GrStyle::SimpleFill();
+ args.fShape = &shape;
args.fAntiAlias = useCoverageAA;
args.fGammaCorrect = fDrawContext->isGammaCorrect();
pr->drawPath(args);
void GrDrawContext::internalDrawPath(const GrClip& clip,
const GrPaint& paint,
const SkMatrix& viewMatrix,
- const SkPath& origPath,
- const GrStyle& origStyle) {
+ const SkPath& path,
+ const GrStyle& style) {
ASSERT_SINGLE_OWNER
RETURN_IF_ABANDONED
- SkASSERT(!origPath.isEmpty());
+ SkASSERT(!path.isEmpty());
bool useCoverageAA = should_apply_coverage_aa(paint, fRenderTarget.get());
constexpr bool kHasUserStencilSettings = false;
useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType
: GrPathRendererChain::kColor_DrawType;
- SkTLazy<SkPath> tmpPath;
- SkTLazy<GrStyle> tmpStyle;
-
+ GrShape shape(path, style);
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fShaderCaps = fDrawingManager->getContext()->caps()->shaderCaps();
canDrawArgs.fViewMatrix = &viewMatrix;
- canDrawArgs.fPath = &origPath;
- canDrawArgs.fStyle = &origStyle;
+ canDrawArgs.fShape = &shape;
canDrawArgs.fAntiAlias = useCoverageAA;
canDrawArgs.fHasUserStencilSettings = kHasUserStencilSettings;
canDrawArgs.fIsStencilBufferMSAA = isStencilBufferMSAA;
GrPathRenderer* pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
SkScalar styleScale = GrStyle::MatrixToScaleFactor(viewMatrix);
- if (!pr && canDrawArgs.fStyle->pathEffect()) {
+ if (!pr && shape.style().pathEffect()) {
// It didn't work above, so try again with the path effect applied.
- SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
- if (!canDrawArgs.fStyle->applyPathEffectToPath(tmpPath.init(), &rec, *canDrawArgs.fPath,
- styleScale)) {
- GrStyle noPathEffect(canDrawArgs.fStyle->strokeRec(), nullptr);
- this->internalDrawPath(clip, paint, viewMatrix, *canDrawArgs.fPath, noPathEffect);
- return;
- }
- tmpStyle.init(rec, nullptr);
- canDrawArgs.fPath = tmpPath.get();
- canDrawArgs.fStyle = tmpStyle.get();
- if (canDrawArgs.fPath->isEmpty()) {
+ shape = shape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
+ if (shape.isEmpty()) {
return;
}
-
pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
}
if (!pr) {
- SkASSERT(!canDrawArgs.fStyle->pathEffect());
- if (canDrawArgs.fStyle->strokeRec().needToApply()) {
- if (!tmpPath.isValid()) {
- tmpPath.init();
- }
- // It didn't work above, so try again by applying the stroke to the geometry.
- SkStrokeRec::InitStyle fillOrHairline;
- if (!canDrawArgs.fStyle->applyToPath(tmpPath.get(), &fillOrHairline,
- *canDrawArgs.fPath, styleScale)) {
+ if (shape.style().applies()) {
+ shape = shape.applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale);
+ if (shape.isEmpty()) {
return;
}
- if (!tmpStyle.isValid()) {
- tmpStyle.init(fillOrHairline);
- } else {
- tmpStyle.get()->resetToInitStyle(fillOrHairline);
- }
- canDrawArgs.fPath = tmpPath.get();
- canDrawArgs.fStyle = tmpStyle.get();
- if (canDrawArgs.fPath->isEmpty()) {
- return;
- }
-
- pr = fDrawingManager->getPathRenderer(canDrawArgs, false, type);
}
-
// This time, allow SW renderer
pr = fDrawingManager->getPathRenderer(canDrawArgs, true, type);
}
- if (nullptr == pr) {
+ if (!pr) {
#ifdef SK_DEBUG
SkDebugf("Unable to find path renderer compatible with path.\n");
#endif
args.fClip = &clip;
args.fColor = paint.getColor();
args.fViewMatrix = &viewMatrix;
- args.fPath = canDrawArgs.fPath;
- args.fStyle = canDrawArgs.fStyle;
+ args.fShape = canDrawArgs.fShape;
args.fAntiAlias = useCoverageAA;
args.fGammaCorrect = this->isGammaCorrect();
pr->drawPath(args);
#include "GrDrawContext.h"
#include "GrPaint.h"
#include "GrResourceProvider.h"
-#include "GrStyle.h"
+#include "GrShape.h"
#include "SkDrawProcs.h"
#include "SkTArray.h"
* This function is to get the stencil support for a particular path. The path's fill must
* not be an inverse type. The path will always be filled and not stroked.
*
- * @param path the path that will be drawn
+ * @param shape the shape that will be drawn. Must be simple fill styled and non-inverse
+ * filled.
*/
- StencilSupport getStencilSupport(const SkPath& path) const {
+ StencilSupport getStencilSupport(const GrShape& shape) const {
+ SkDEBUGCODE(SkPath path;)
+ SkDEBUGCODE(shape.asPath(&path);)
+ SkASSERT(shape.style().isSimpleFill());
SkASSERT(!path.isInverseFillType());
- return this->onGetStencilSupport(path);
+ return this->onGetStencilSupport(shape);
}
/** Args to canDrawPath()
* fShaderCaps The shader caps
* fPipelineBuilder The pipelineBuilder
* fViewMatrix The viewMatrix
- * fPath The path to draw
- * fStyle The styling info (path effect, stroking info)
+ * fShape The shape to draw
* fAntiAlias True if anti-aliasing is required.
*/
struct CanDrawPathArgs {
const GrShaderCaps* fShaderCaps;
const SkMatrix* fViewMatrix;
- const SkPath* fPath;
- const GrStyle* fStyle;
+ const GrShape* fShape;
bool fAntiAlias;
// These next two are only used by GrStencilAndCoverPathRenderer
bool fHasUserStencilSettings;
bool fIsStencilBufferMSAA;
+#ifdef SK_DEBUG
void validate() const {
SkASSERT(fShaderCaps);
SkASSERT(fViewMatrix);
- SkASSERT(fPath);
- SkASSERT(fStyle);
- SkASSERT(!fPath->isEmpty());
+ SkASSERT(fShape);
}
+#endif
};
/**
* fClip The clip
* fColor Color to render with
* fViewMatrix The viewMatrix
- * fPath the path to draw.
- * fStyle the style information (path effect, stroke info)
+ * fShape The shape to draw
* fAntiAlias true if anti-aliasing is required.
* fGammaCorrect true if gamma-correct rendering is to be used.
*/
const GrClip* fClip;
GrColor fColor;
const SkMatrix* fViewMatrix;
- const SkPath* fPath;
- const GrStyle* fStyle;
+ const GrShape* fShape;
bool fAntiAlias;
bool fGammaCorrect;
-
+#ifdef SK_DEBUG
void validate() const {
SkASSERT(fResourceProvider);
SkASSERT(fPaint);
SkASSERT(fDrawContext);
SkASSERT(fClip);
SkASSERT(fViewMatrix);
- SkASSERT(fPath);
- SkASSERT(fStyle);
- SkASSERT(!fPath->isEmpty());
+ SkASSERT(fShape);
}
+#endif
};
/**
CanDrawPathArgs canArgs;
canArgs.fShaderCaps = args.fResourceProvider->caps()->shaderCaps();
canArgs.fViewMatrix = args.fViewMatrix;
- canArgs.fPath = args.fPath;
- canArgs.fStyle = args.fStyle;
+ canArgs.fShape = args.fShape;
canArgs.fAntiAlias = args.fAntiAlias;
canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
canArgs.fIsStencilBufferMSAA = args.fDrawContext->isStencilBufferMultisampled();
SkASSERT(this->canDrawPath(canArgs));
if (!args.fUserStencilSettings->isUnused()) {
- SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fPath));
- SkASSERT(args.fStyle->isSimpleFill());
+ SkPath path;
+ args.fShape->asPath(&path);
+ SkASSERT(args.fShape->style().isSimpleFill());
+ SkASSERT(kNoRestriction_StencilSupport == this->getStencilSupport(*args.fShape));
}
#endif
return this->onDrawPath(args);
GrDrawContext* fDrawContext;
const GrFixedClip* fClip;
const SkMatrix* fViewMatrix;
- const SkPath* fPath;
bool fIsAA;
+ const GrShape* fShape;
+#ifdef SK_DEBUG
void validate() const {
SkASSERT(fResourceProvider);
SkASSERT(fDrawContext);
SkASSERT(fViewMatrix);
- SkASSERT(fPath);
- SkASSERT(!fPath->isEmpty());
+ SkASSERT(fShape);
+ SkASSERT(fShape->style().isSimpleFill())
+ SkPath path;
+ fShape->asPath(&path);
+ SkASSERT(!path.isInverseFillType());
}
+#endif
};
/**
*/
void stencilPath(const StencilPathArgs& args) {
SkDEBUGCODE(args.validate();)
- SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fPath));
+ SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(*args.fShape));
this->onStencilPath(args);
}
/**
* Subclass overrides if it has any limitations of stenciling support.
*/
- virtual StencilSupport onGetStencilSupport(const SkPath&) const {
+ virtual StencilSupport onGetStencilSupport(const GrShape&) const {
return kNoRestriction_StencilSupport;
}
drawArgs.fDrawContext = args.fDrawContext;
drawArgs.fColor = GrColor_WHITE;
drawArgs.fViewMatrix = args.fViewMatrix;
- drawArgs.fPath = args.fPath;
- drawArgs.fStyle = &GrStyle::SimpleFill();
+ drawArgs.fShape = args.fShape;
drawArgs.fAntiAlias = false; // In this case the MSAA handles the AA so we want to draw BW
drawArgs.fGammaCorrect = false;
this->drawPath(drawArgs);
}
if (minStencilSupport != GrPathRenderer::kNoSupport_StencilSupport) {
// We don't support (and shouldn't need) stenciling of non-fill paths.
- if (!args.fStyle->isSimpleFill()) {
+ if (!args.fShape->style().isSimpleFill()) {
return nullptr;
}
}
for (int i = 0; i < fChain.count(); ++i) {
if (fChain[i]->canDrawPath(args)) {
if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
- GrPathRenderer::StencilSupport support =
- fChain[i]->getStencilSupport(*args.fPath);
+ GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(*args.fShape);
if (support < minStencilSupport) {
continue;
} else if (stencilSupport) {
#include "GrContext.h"
#include "batches/GrDrawBatch.h"
#include "GrDrawContext.h"
-#include "GrGpu.h"
#include "GrPipelineBuilder.h"
-#include "GrStyle.h"
+#include "GrShape.h"
-#include "SkData.h"
#include "SkDistanceFieldGen.h"
-#include "SkStrokeRec.h"
#include "batches/GrRectBatchFactory.h"
/**
* Draw a single path element of the clip stack into the accumulation bitmap
*/
-void GrSWMaskHelper::drawPath(const SkPath& path, const GrStyle& style, SkRegion::Op op,
- bool antiAlias, uint8_t alpha) {
+void GrSWMaskHelper::drawShape(const GrShape& shape, SkRegion::Op op, bool antiAlias,
+ uint8_t alpha) {
SkPaint paint;
- paint.setPathEffect(sk_ref_sp(style.pathEffect()));
- style.strokeRec().applyToPaint(&paint);
+ paint.setPathEffect(sk_ref_sp(shape.style().pathEffect()));
+ shape.style().strokeRec().applyToPaint(&paint);
paint.setAntiAlias(antiAlias);
+ SkPath path;
+ shape.asPath(&path);
if (SkRegion::kReplace_Op == op && 0xFF == alpha) {
SkASSERT(0xFF == paint.getAlpha());
fDraw.drawPathCoverage(path, paint);
////////////////////////////////////////////////////////////////////////////////
/**
- * Software rasterizes path to A8 mask (possibly using the context's matrix)
- * and uploads the result to a scratch texture. Returns the resulting
- * texture on success; nullptr on failure.
+ * Software rasterizes shape to A8 mask and uploads the result to a scratch texture. Returns the
+ * resulting texture on success; nullptr on failure.
*/
-GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrTextureProvider* texProvider,
- const SkPath& path,
- const GrStyle& style,
- const SkIRect& resultBounds,
- bool antiAlias,
- const SkMatrix* matrix) {
+GrTexture* GrSWMaskHelper::DrawShapeMaskToTexture(GrTextureProvider* texProvider,
+ const GrShape& shape,
+ const SkIRect& resultBounds,
+ bool antiAlias,
+ const SkMatrix* matrix) {
GrSWMaskHelper helper(texProvider);
if (!helper.init(resultBounds, matrix)) {
return nullptr;
}
- helper.drawPath(path, style, SkRegion::kReplace_Op, antiAlias, 0xFF);
+ helper.drawShape(shape, SkRegion::kReplace_Op, antiAlias, 0xFF);
GrTexture* texture(helper.createTexture());
if (!texture) {
return texture;
}
-void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
- GrDrawContext* drawContext,
- const GrPaint* paint,
- const GrUserStencilSettings* userStencilSettings,
- const GrClip& clip,
- GrColor color,
- const SkMatrix& viewMatrix,
- const SkIRect& rect) {
+void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture,
+ GrDrawContext* drawContext,
+ const GrPaint* paint,
+ const GrUserStencilSettings* userStencilSettings,
+ const GrClip& clip,
+ GrColor color,
+ const SkMatrix& viewMatrix,
+ const SkIRect& rect) {
SkMatrix invert;
if (!viewMatrix.invert(&invert)) {
return;
class GrClip;
class GrPaint;
+class GrShape;
class GrTextureProvider;
class GrStyle;
class GrTexture;
-class SkPath;
-class SkStrokeRec;
struct GrUserStencilSettings;
/**
void drawRect(const SkRect& rect, SkRegion::Op op, bool antiAlias, uint8_t alpha);
// Draw a single path into the accumuation bitmap using the specified op
- void drawPath(const SkPath& path, const GrStyle& style, SkRegion::Op op,
- bool antiAlias, uint8_t alpha);
+ void drawShape(const GrShape&, SkRegion::Op op, bool antiAlias, uint8_t alpha);
// Move the mask generation results from the internal bitmap to the gpu.
void toTexture(GrTexture* texture);
// Canonical usage utility that draws a single path and uploads it
// to the GPU. The result is returned.
- static GrTexture* DrawPathMaskToTexture(GrTextureProvider*,
- const SkPath& path,
- const GrStyle& style,
- const SkIRect& resultBounds,
- bool antiAlias,
- const SkMatrix* matrix);
-
- // This utility routine is used to add a path's mask to some other draw.
+ static GrTexture* DrawShapeMaskToTexture(GrTextureProvider*,
+ const GrShape&,
+ const SkIRect& resultBounds,
+ bool antiAlias,
+ const SkMatrix* matrix);
+
+ // This utility routine is used to add a shape's mask to some other draw.
// The ClipMaskManager uses it to accumulate clip masks while the
// GrSoftwarePathRenderer uses it to fulfill a drawPath call.
// It draws with "texture" as a path mask into "target" using "rect" as
// the draw state can be used to hold the mask texture stage.
// This method is really only intended to be used with the
// output of DrawPathMaskToTexture.
- static void DrawToTargetWithPathMask(GrTexture* texture,
- GrDrawContext*,
- const GrPaint* paint,
- const GrUserStencilSettings* userStencilSettings,
- const GrClip&,
- GrColor,
- const SkMatrix& viewMatrix,
- const SkIRect& rect);
+ static void DrawToTargetWithShapeMask(GrTexture* texture,
+ GrDrawContext*,
+ const GrPaint* paint,
+ const GrUserStencilSettings* userStencilSettings,
+ const GrClip&,
+ GrColor,
+ const SkMatrix& viewMatrix,
+ const SkIRect& rect);
private:
// Helper function to get a scratch texture suitable for capturing the
////////////////////////////////////////////////////////////////////////////////
bool GrSoftwarePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- return SkToBool(fTexProvider);
+ // Pass on any style that applies. The caller will apply the style if a suitable renderer is
+ // not found and try again with the new GrShape.
+ return !args.fShape->style().applies() && SkToBool(fTexProvider);
}
namespace {
// gets device coord bounds of path (not considering the fill) and clip. The
// path bounds will be a subset of the clip bounds. returns false if
// path bounds would be empty.
-bool get_path_and_clip_bounds(int width, int height,
- const GrClip& clip,
- const SkPath& path,
- const SkMatrix& matrix,
- SkIRect* devPathBounds,
- SkIRect* devClipBounds) {
+bool get_shape_and_clip_bounds(int width, int height,
+ const GrClip& clip,
+ const GrShape& shape,
+ const SkMatrix& matrix,
+ SkIRect* devShapeBounds,
+ SkIRect* devClipBounds) {
// compute bounds as intersection of rt size, clip, and path
clip.getConservativeBounds(width, height, devClipBounds);
if (devClipBounds->isEmpty()) {
- *devPathBounds = SkIRect::MakeWH(width, height);
+ *devShapeBounds = SkIRect::MakeWH(width, height);
return false;
}
-
- if (!path.getBounds().isEmpty()) {
- SkRect pathSBounds;
- matrix.mapRect(&pathSBounds, path.getBounds());
- SkIRect pathIBounds;
- pathSBounds.roundOut(&pathIBounds);
- *devPathBounds = *devClipBounds;
- if (!devPathBounds->intersect(pathIBounds)) {
+ SkRect shapeBounds;
+ shape.styledBounds(&shapeBounds);
+ if (!shapeBounds.isEmpty()) {
+ SkRect shapeSBounds;
+ matrix.mapRect(&shapeSBounds, shapeBounds);
+ SkIRect shapeIBounds;
+ shapeSBounds.roundOut(&shapeIBounds);
+ *devShapeBounds = *devClipBounds;
+ if (!devShapeBounds->intersect(shapeIBounds)) {
// set the correct path bounds, as this would be used later.
- *devPathBounds = pathIBounds;
+ *devShapeBounds = shapeIBounds;
return false;
}
} else {
- *devPathBounds = SkIRect::EmptyIRect();
+ *devShapeBounds = SkIRect::EmptyIRect();
return false;
}
return true;
return false;
}
- SkIRect devPathBounds, devClipBounds;
- if (!get_path_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(),
- *args.fClip, *args.fPath,
- *args.fViewMatrix, &devPathBounds, &devClipBounds)) {
- if (args.fPath->isInverseFillType()) {
+ // We really need to know if the shape will be inverse filled or not
+ bool inverseFilled = false;
+ SkTLazy<GrShape> tmpShape;
+ SkASSERT(!args.fShape->style().applies())
+ inverseFilled = args.fShape->inverseFilled();
+
+ SkIRect devShapeBounds, devClipBounds;
+ if (!get_shape_and_clip_bounds(args.fDrawContext->width(), args.fDrawContext->height(),
+ *args.fClip, *args.fShape,
+ *args.fViewMatrix, &devShapeBounds, &devClipBounds)) {
+ if (inverseFilled) {
DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
*args.fClip, args.fColor,
- *args.fViewMatrix, devClipBounds, devPathBounds);
+ *args.fViewMatrix, devClipBounds, devShapeBounds);
+
}
return true;
}
SkAutoTUnref<GrTexture> texture(
- GrSWMaskHelper::DrawPathMaskToTexture(fTexProvider, *args.fPath, *args.fStyle,
- devPathBounds,
- args.fAntiAlias, args.fViewMatrix));
+ GrSWMaskHelper::DrawShapeMaskToTexture(fTexProvider, *args.fShape, devShapeBounds,
+ args.fAntiAlias, args.fViewMatrix));
if (nullptr == texture) {
return false;
}
- GrSWMaskHelper::DrawToTargetWithPathMask(texture, args.fDrawContext, args.fPaint,
- args.fUserStencilSettings,
- *args.fClip, args.fColor, *args.fViewMatrix,
- devPathBounds);
+ GrSWMaskHelper::DrawToTargetWithShapeMask(texture, args.fDrawContext, args.fPaint,
+ args.fUserStencilSettings,
+ *args.fClip, args.fColor, *args.fViewMatrix,
+ devShapeBounds);
- if (args.fPath->isInverseFillType()) {
+ if (inverseFilled) {
DrawAroundInvPath(args.fDrawContext, args.fPaint, args.fUserStencilSettings,
*args.fClip, args.fColor,
- *args.fViewMatrix, devClipBounds, devPathBounds);
+ *args.fViewMatrix, devClipBounds, devShapeBounds);
}
return true;
const SkIRect& devClipBounds,
const SkIRect& devPathBounds);
- StencilSupport onGetStencilSupport(const SkPath&) const override {
+ StencilSupport onGetStencilSupport(const GrShape&) const override {
return GrPathRenderer::kNoSupport_StencilSupport;
}
/** Is this style a hairline with no path effect? */
bool isSimpleHairline() const { return fStrokeRec.isHairlineStyle() && !fPathEffect; }
+ bool couldBeHairline() const {
+ // If the original stroke rec has hairline style then either a null or dash patheffect
+ // would preserve the hairline status. An arbitrary path effect could introduce hairline
+ // style.
+ return this->strokeRec().isHairlineStyle() || this->hasNonDashPathEffect();
+ }
+
SkPathEffect* pathEffect() const { return fPathEffect.get(); }
bool hasPathEffect() const { return SkToBool(fPathEffect.get()); }
bool GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
return (args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
- args.fStyle->isSimpleFill() && !args.fPath->isInverseFillType() &&
- args.fPath->isConvex());
+ args.fShape->style().isSimpleFill() && !args.fShape->inverseFilled() &&
+ args.fShape->knownToBeConvex());
}
// extract the result vertices and indices from the GrAAConvexTessellator
GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
"GrAAConvexPathRenderer::onDrawPath");
SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
-
- if (args.fPath->isEmpty()) {
- return true;
- }
+ SkASSERT(!args.fShape->isEmpty());
AAConvexPathBatch::Geometry geometry;
geometry.fColor = args.fColor;
geometry.fViewMatrix = *args.fViewMatrix;
- geometry.fPath = *args.fPath;
+ args.fShape->asPath(&geometry.fPath);
SkAutoTUnref<GrDrawBatch> batch(AAConvexPathBatch::Create(geometry));
////////////////////////////////////////////////////////////////////////////////
bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// We don't currently apply the dash or factor it into the DF key. (skbug.com/5082)
- if (args.fStyle->pathEffect()) {
+ if (args.fShape->style().pathEffect()) {
return false;
}
// TODO: Support inverse fill
if (!args.fShaderCaps->shaderDerivativeSupport() || !args.fAntiAlias ||
- args.fStyle->isSimpleHairline() || args.fPath->isInverseFillType() ||
- args.fPath->isVolatile()) {
+ args.fShape->style().isSimpleHairline() || args.fShape->mayBeInverseFilledAfterStyling() ||
+ !args.fShape->hasUnstyledKey()) {
return false;
}
// the goal is to accelerate rendering of lots of small paths that may be scaling
SkScalar maxScale = args.fViewMatrix->getMaxScale();
SkRect bounds;
- args.fStyle->adjustBounds(&bounds, args.fPath->getBounds());
+ args.fShape->styledBounds(&bounds);
SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
return maxDim <= kMediumMIP && maxDim * maxScale <= 2.0f*kLargeMIP;
SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
// we've already bailed on inverse filled paths, so this is safe
- if (args.fPath->isEmpty()) {
- return true;
- }
+ SkASSERT(!args.fShape->isEmpty());
if (!fAtlas) {
fAtlas = args.fResourceProvider->createAtlas(kAlpha_8_GrPixelConfig,
}
}
+ const GrStyle& style = args.fShape->style();
// It's ok to ignore style's path effect because canDrawPath filtered out path effects.
- AADistanceFieldPathBatch::Geometry geometry(args.fStyle->strokeRec());
- if (args.fStyle->isSimpleFill()) {
- geometry.fPath = *args.fPath;
- } else {
- args.fStyle->strokeRec().applyToPath(&geometry.fPath, *args.fPath);
- }
- geometry.fColor = args.fColor;
- geometry.fAntiAlias = args.fAntiAlias;
+ AADistanceFieldPathBatch::Geometry geometry(style.strokeRec());
+ args.fShape->asPath(&geometry.fPath);
// Note: this is the generation ID of the _original_ path. When a new path is
// generated due to stroking it is important that the original path's id is used
// for caching.
- geometry.fGenID = args.fPath->getGenerationID();
+ geometry.fGenID = geometry.fPath.getGenerationID();
+ if (!style.isSimpleFill()) {
+ style.strokeRec().applyToPath(&geometry.fPath, geometry.fPath);
+ }
+ geometry.fColor = args.fColor;
+ geometry.fAntiAlias = args.fAntiAlias;
SkAutoTUnref<GrDrawBatch> batch(AADistanceFieldPathBatch::Create(geometry,
*args.fViewMatrix, fAtlas,
virtual ~GrAADistanceFieldPathRenderer();
private:
- StencilSupport onGetStencilSupport(const SkPath&) const override {
+ StencilSupport onGetStencilSupport(const GrShape&) const override {
return GrPathRenderer::kNoSupport_StencilSupport;
}
return false;
}
- if (!IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr)) {
+ if (!IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr)) {
return false;
}
// We don't currently handle dashing in this class though perhaps we should.
- if (args.fStyle->pathEffect()) {
+ if (args.fShape->style().pathEffect()) {
return false;
}
- if (SkPath::kLine_SegmentMask == args.fPath->getSegmentMasks() ||
+ if (SkPath::kLine_SegmentMask == args.fShape->segmentMask() ||
args.fShaderCaps->shaderDerivativeSupport()) {
return true;
}
+
return false;
}
args.fClip->getConservativeBounds(args.fDrawContext->width(), args.fDrawContext->height(),
&devClipBounds);
- SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
- *args.fStyle, devClipBounds));
+ SkPath path;
+ args.fShape->asPath(&path);
+ SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, path,
+ args.fShape->style(), devClipBounds));
GrPipelineBuilder pipelineBuilder(*args.fPaint);
pipelineBuilder.setUserStencil(args.fUserStencilSettings);
-
args.fDrawContext->drawBatch(pipelineBuilder, *args.fClip, batch);
return true;
if (!args.fAntiAlias) {
return false;
}
- if (args.fPath->isInverseFillType()) {
+ if (!args.fShape->knownToBeConvex()) {
return false;
}
- if (!args.fPath->isConvex()) {
+ if (args.fShape->style().pathEffect()) {
return false;
}
- if (args.fStyle->pathEffect()) {
+ if (args.fShape->inverseFilled()) {
return false;
}
- const SkStrokeRec& stroke = args.fStyle->strokeRec();
+ const SkStrokeRec& stroke = args.fShape->style().strokeRec();
if (stroke.getStyle() == SkStrokeRec::kStroke_Style) {
if (!args.fViewMatrix->isSimilarity()) {
return false;
}
SkScalar strokeWidth = args.fViewMatrix->getMaxScale() * stroke.getWidth();
return strokeWidth >= 1.0f && strokeWidth <= kMaxStrokeWidth &&
- SkPathPriv::IsClosedSingleContour(*args.fPath) &&
+ args.fShape->knownToBeClosed() &&
stroke.getJoin() != SkPaint::Join::kRound_Join;
}
return stroke.getStyle() == SkStrokeRec::kFill_Style;
GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
"GrAALinearizingConvexPathRenderer::onDrawPath");
SkASSERT(!args.fDrawContext->isUnifiedMultisampled());
+ SkASSERT(!args.fShape->isEmpty());
- if (args.fPath->isEmpty()) {
- return true;
- }
AAFlatteningConvexPathBatch::Geometry geometry;
geometry.fColor = args.fColor;
geometry.fViewMatrix = *args.fViewMatrix;
- geometry.fPath = *args.fPath;
- bool fill = args.fStyle->isSimpleFill();
- geometry.fStrokeWidth = fill ? -1.0f : args.fStyle->strokeRec().getWidth();
- geometry.fJoin = fill ? SkPaint::Join::kMiter_Join : args.fStyle->strokeRec().getJoin();
- geometry.fMiterLimit = args.fStyle->strokeRec().getMiter();
+ args.fShape->asPath(&geometry.fPath);
+ bool fill = args.fShape->style().isSimpleFill();
+ const SkStrokeRec& stroke = args.fShape->style().strokeRec();
+ geometry.fStrokeWidth = fill ? -1.0f : stroke.getWidth();
+ geometry.fJoin = fill ? SkPaint::Join::kMiter_Join : stroke.getJoin();
+ geometry.fMiterLimit = stroke.getMiter();
SkAutoTUnref<GrDrawBatch> batch(AAFlatteningConvexPathBatch::Create(geometry));
bool GrDashLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
SkPoint pts[2];
- if (args.fStyle->isDashed() && args.fPath->isLine(pts)) {
- return GrDashingEffect::CanDrawDashLine(pts, *args.fStyle, *args.fViewMatrix);
+ if (args.fShape->style().isDashed() && args.fShape->asLine(pts)) {
+ return GrDashingEffect::CanDrawDashLine(pts, args.fShape->style(), *args.fViewMatrix);
}
return false;
}
aaMode = GrDashingEffect::AAMode::kNone;
}
SkPoint pts[2];
- SkAssertResult(args.fPath->isLine(pts));
+ SkAssertResult(args.fShape->asLine(pts));
SkAutoTUnref<GrDrawBatch> batch(GrDashingEffect::CreateDashLineBatch(args.fColor,
*args.fViewMatrix,
pts,
aaMode,
- *args.fStyle));
+ args.fShape->style()));
if (!batch) {
return false;
}
private:
bool onCanDrawPath(const CanDrawPathArgs&) const override;
- StencilSupport onGetStencilSupport(const SkPath&) const override {
+ StencilSupport onGetStencilSupport(const GrShape&) const override {
return kNoSupport_StencilSupport;
}
#define STENCIL_OFF 0 // Always disable stencil (even when needed)
-static inline bool single_pass_path(const SkPath& path, const SkStrokeRec& stroke) {
+static inline bool single_pass_shape(const GrShape& shape) {
#if STENCIL_OFF
return true;
#else
- if (!stroke.isHairlineStyle() && !path.isInverseFillType()) {
- return path.isConvex();
+ if (!shape.style().couldBeHairline() && !shape.inverseFilled()) {
+ return shape.knownToBeConvex();
}
return false;
#endif
}
GrPathRenderer::StencilSupport
-GrDefaultPathRenderer::onGetStencilSupport(const SkPath& path) const {
- if (single_pass_path(path, SkStrokeRec(SkStrokeRec::kFill_InitStyle))) {
+GrDefaultPathRenderer::onGetStencilSupport(const GrShape& shape) const {
+ if (single_pass_shape(shape)) {
return GrPathRenderer::kNoRestriction_StencilSupport;
} else {
return GrPathRenderer::kStencilOnly_StencilSupport;
const GrClip& clip,
GrColor color,
const SkMatrix& viewMatrix,
- const SkPath& path,
- const GrStyle& origStyle,
+ const GrShape& shape,
bool stencilOnly) {
- const GrStyle* style = &origStyle;
+ SkPath path;
+ shape.asPath(&path);
SkScalar hairlineCoverage;
uint8_t newCoverage = 0xff;
bool isHairline = false;
- if (IsStrokeHairlineOrEquivalent(*style, viewMatrix, &hairlineCoverage)) {
+ if (IsStrokeHairlineOrEquivalent(shape.style(), viewMatrix, &hairlineCoverage)) {
newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff);
- style = &GrStyle::SimpleHairline();
isHairline = true;
} else {
- SkASSERT(style->isSimpleFill());
+ SkASSERT(shape.style().isSimpleFill());
}
int passCount = 0;
lastPassIsBounds = false;
drawFace[0] = GrPipelineBuilder::kBoth_DrawFace;
} else {
- if (single_pass_path(path, style->strokeRec())) {
+ if (single_pass_shape(shape)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// this class can draw any path with any simple fill style but doesn't do any anti-aliasing.
return !args.fAntiAlias &&
- (args.fStyle->isSimpleFill() || IsStrokeHairlineOrEquivalent(*args.fStyle,
- *args.fViewMatrix,
- nullptr));
+ (args.fShape->style().isSimpleFill() ||
+ IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr));
}
bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
*args.fClip,
args.fColor,
*args.fViewMatrix,
- *args.fPath,
- *args.fStyle,
+ *args.fShape,
false);
}
void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
"GrDefaultPathRenderer::onStencilPath");
- SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
- SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
+ SkASSERT(!args.fShape->inverseFilled());
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Make());
paint.setAntiAlias(args.fIsAA);
- this->internalDrawPath(args.fDrawContext,
- paint,
- &GrUserStencilSettings::kUnused,
- *args.fClip,
- GrColor_WHITE,
- *args.fViewMatrix,
- *args.fPath,
- GrStyle::SimpleFill(),
- true);
+ this->internalDrawPath(args.fDrawContext, paint, &GrUserStencilSettings::kUnused, *args.fClip,
+ GrColor_WHITE, *args.fViewMatrix, *args.fShape, true);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
private:
- StencilSupport onGetStencilSupport(const SkPath&) const override;
+ StencilSupport onGetStencilSupport(const GrShape&) const override;
bool onCanDrawPath(const CanDrawPathArgs&) const override;
const GrClip&,
GrColor,
const SkMatrix& viewMatrix,
- const SkPath&,
- const GrStyle&,
+ const GrShape&,
bool stencilOnly);
bool fSeparateStencil;
////////////////////////////////////////////////////////////////////////////////
// Helpers for drawPath
-static inline bool single_pass_path(const SkPath& path) {
- if (!path.isInverseFillType()) {
- return path.isConvex();
+static inline bool single_pass_shape(const GrShape& shape) {
+ if (!shape.inverseFilled()) {
+ return shape.knownToBeConvex();
}
return false;
}
-GrPathRenderer::StencilSupport
-GrMSAAPathRenderer::onGetStencilSupport(const SkPath& path) const {
- if (single_pass_path(path)) {
+GrPathRenderer::StencilSupport GrMSAAPathRenderer::onGetStencilSupport(const GrShape& shape) const {
+ if (single_pass_shape(shape)) {
return GrPathRenderer::kNoRestriction_StencilSupport;
} else {
return GrPathRenderer::kStencilOnly_StencilSupport;
const GrClip& clip,
GrColor color,
const SkMatrix& viewMatrix,
- const SkPath& path,
+ const GrShape& shape,
bool stencilOnly) {
+ SkASSERT(shape.style().isSimpleFill());
+ SkPath path;
+ shape.asPath(&path);
+
int passCount = 0;
const GrUserStencilSettings* passes[3];
GrPipelineBuilder::DrawFace drawFace[3];
bool reverse = false;
bool lastPassIsBounds;
- if (single_pass_path(path)) {
+ if (single_pass_shape(shape)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
// This path renderer does not support hairlines. We defer on anything that could be handled
// as a hairline by another path renderer. Also, arbitrary path effects could produce
// a hairline result.
- return !IsStrokeHairlineOrEquivalent(*args.fStyle, *args.fViewMatrix, nullptr) &&
- !args.fStyle->strokeRec().isHairlineStyle() &&
- !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias;
+ return !IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr) &&
+ !args.fShape->style().couldBeHairline() && !args.fAntiAlias;
}
bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
"GrMSAAPathRenderer::onDrawPath");
- SkPath tmpPath;
- const SkPath* path;
- if (args.fStyle->applies()) {
- SkStrokeRec::InitStyle fill;
+ SkTLazy<GrShape> tmpShape;
+ const GrShape* shape = args.fShape;
+ if (shape->style().applies()) {
SkScalar styleScale = GrStyle::MatrixToScaleFactor(*args.fViewMatrix);
- if (!args.fStyle->applyToPath(&tmpPath, &fill, *args.fPath, styleScale)) {
- return false;
- }
- // We don't accept styles that are hairlines or have path effects that could produce
- // hairlines.
- SkASSERT(SkStrokeRec::kFill_InitStyle == fill);
- path = &tmpPath;
- } else {
- path = args.fPath;
+ tmpShape.init(args.fShape->applyStyle(GrStyle::Apply::kPathEffectAndStrokeRec, styleScale));
+ shape = tmpShape.get();
}
return this->internalDrawPath(args.fDrawContext,
*args.fPaint,
*args.fClip,
args.fColor,
*args.fViewMatrix,
- *path,
+ *shape,
false);
}
void GrMSAAPathRenderer::onStencilPath(const StencilPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
"GrMSAAPathRenderer::onStencilPath");
- SkASSERT(SkPath::kInverseEvenOdd_FillType != args.fPath->getFillType());
- SkASSERT(SkPath::kInverseWinding_FillType != args.fPath->getFillType());
+ SkASSERT(args.fShape->style().isSimpleFill());
+ SkASSERT(!args.fShape->mayBeInverseFilledAfterStyling());
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Make());
paint.setAntiAlias(args.fIsAA);
- this->internalDrawPath(args.fDrawContext,
- paint,
- &GrUserStencilSettings::kUnused,
- *args.fClip,
- GrColor_WHITE,
- *args.fViewMatrix,
- *args.fPath,
- true);
+ this->internalDrawPath(args.fDrawContext, paint, &GrUserStencilSettings::kUnused, *args.fClip,
+ GrColor_WHITE, *args.fViewMatrix, *args.fShape, true);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
class SK_API GrMSAAPathRenderer : public GrPathRenderer {
private:
- StencilSupport onGetStencilSupport(const SkPath&) const override;
+ StencilSupport onGetStencilSupport(const GrShape&) const override;
bool onCanDrawPath(const CanDrawPathArgs&) const override;
const GrClip&,
GrColor,
const SkMatrix& viewMatrix,
- const SkPath&,
+ const GrShape&,
bool stencilOnly);
typedef GrPathRenderer INHERITED;
bool GrPLSPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// We have support for even-odd rendering, but are having some troublesome
// seams. Disable in the presence of even-odd for now.
+ SkPath path;
+ args.fShape->asPath(&path);
return args.fShaderCaps->shaderDerivativeSupport() && args.fAntiAlias &&
- args.fStyle->isSimpleFill() && !args.fPath->isInverseFillType() &&
- args.fPath->getFillType() == SkPath::FillType::kWinding_FillType;
+ args.fShape->style().isSimpleFill() && !path.isInverseFillType() &&
+ path.getFillType() == SkPath::FillType::kWinding_FillType;
}
class PLSPathBatch : public GrVertexBatch {
SkDEBUGCODE(bool inPLSDraw = false;)
bool GrPLSPathRenderer::onDrawPath(const DrawPathArgs& args) {
- if (args.fPath->isEmpty()) {
- return true;
- }
+ SkASSERT(!args.fShape->isEmpty())
SkASSERT(!inPLSDraw);
SkDEBUGCODE(inPLSDraw = true;)
PLSPathBatch::Geometry geometry;
geometry.fColor = args.fColor;
geometry.fViewMatrix = *args.fViewMatrix;
- geometry.fPath = *args.fPath;
+ args.fShape->asPath(&geometry.fPath);
SkAutoTUnref<GrDrawBatch> batch(PLSPathBatch::Create(geometry));
}
bool GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- // GrPath doesn't support hairline paths. Also, an arbitrary path effect could change
- // the style type to hairline.
- if (args.fStyle->hasNonDashPathEffect() || args.fStyle->strokeRec().isHairlineStyle()) {
+ // GrPath doesn't support hairline paths.
+ if (args.fShape->style().couldBeHairline()) {
return false;
}
if (args.fHasUserStencilSettings) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
"GrStencilAndCoverPathRenderer::onStencilPath");
SkASSERT(!args.fIsAA || args.fDrawContext->isStencilBufferMultisampled());
+ SkPath path;
+ args.fShape->asPath(&path);
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Make());
const GrPipelineBuilder pipelineBuilder(paint, args.fIsAA);
- SkASSERT(!args.fPath->isInverseFillType());
- SkAutoTUnref<GrPath> path(get_gr_path(fResourceProvider, *args.fPath, GrStyle::SimpleFill()));
- args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder,
- *args.fClip,
- *args.fViewMatrix,
- path,
- path->getFillType());
+ SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, GrStyle::SimpleFill()));
+ args.fDrawContext->drawContextPriv().stencilPath(pipelineBuilder, *args.fClip,
+ *args.fViewMatrix, p, p->getFillType());
}
bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fDrawContext->auditTrail(),
"GrStencilAndCoverPathRenderer::onDrawPath");
SkASSERT(!args.fPaint->isAntiAlias() || args.fDrawContext->isStencilBufferMultisampled());
- SkASSERT(!args.fStyle->strokeRec().isHairlineStyle());
- const SkPath& path = *args.fPath;
+ SkASSERT(!args.fShape->style().strokeRec().isHairlineStyle());
+
const SkMatrix& viewMatrix = *args.fViewMatrix;
- SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, *args.fStyle));
+ SkPath path;
+ args.fShape->asPath(&path);
+
+ SkAutoTUnref<GrPath> p(get_gr_path(fResourceProvider, path, args.fShape->style()));
if (path.isInverseFillType()) {
static constexpr GrUserStencilSettings kInvertedCoverPass(
private:
- StencilSupport onGetStencilSupport(const SkPath&) const override {
+ StencilSupport onGetStencilSupport(const GrShape&) const override {
return GrPathRenderer::kStencilOnly_StencilSupport;
}
// 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->strokeRec().isHairlineStyle() &&
- !args.fStyle->hasNonDashPathEffect() && !args.fAntiAlias && !args.fPath->isConvex();
+ return !IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr) &&
+ !args.fShape->style().strokeRec().isHairlineStyle() &&
+ !args.fShape->style().hasNonDashPathEffect() && !args.fAntiAlias &&
+ !args.fShape->knownToBeConvex();
}
class TessellatingPathBatch : public GrVertexBatch {
return false;
}
vmi.mapRect(&clipBounds);
- SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, *args.fPath,
- *args.fStyle, *args.fViewMatrix,
+ SkPath path;
+ args.fShape->asPath(&path);
+ SkAutoTUnref<GrDrawBatch> batch(TessellatingPathBatch::Create(args.fColor, path,
+ args.fShape->style(),
+ *args.fViewMatrix,
clipBounds));
GrPipelineBuilder pipelineBuilder(*args.fPaint, args.fDrawContext->mustUseHWAA(*args.fPaint));
private:
bool onCanDrawPath(const CanDrawPathArgs& ) const override;
- StencilSupport onGetStencilSupport(const SkPath&) const override {
+ StencilSupport onGetStencilSupport(const GrShape&) const override {
return GrPathRenderer::kNoSupport_StencilSupport;
}
args.fResourceProvider = rp;
args.fColor = GrColor_WHITE;
args.fViewMatrix = &SkMatrix::I();
- args.fPath = &path;
- args.fStyle = &style;
+ GrShape shape(path, style);
+ args.fShape = &shape;
args.fAntiAlias = false;
tess.drawPath(args);
}