Use GrShape in GrPathRenderer.

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2081383006

Review-Url: https://codereview.chromium.org/2081383006
This commit is contained in:
bsalomon 2016-06-24 10:42:16 -07:00 committed by Commit bot
parent c2fde8b227
commit 8acedde597
26 changed files with 274 additions and 319 deletions

View File

@ -91,11 +91,11 @@ bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
: 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();
@ -615,11 +615,11 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
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();
@ -658,6 +658,7 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
viewMatrix, element->getRect());
} else {
if (!clipPath.isEmpty()) {
GrShape shape(clipPath, GrStyle::SimpleFill());
if (canRenderDirectToStencil) {
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Make());
@ -671,8 +672,7 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
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);
@ -682,8 +682,8 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
args.fDrawContext = drawContext;
args.fClip = &clip;
args.fViewMatrix = &viewMatrix;
args.fPath = &clipPath;
args.fIsAA = element->isAA();
args.fShape = &shape;
pr->stencilPath(args);
}
}
@ -700,10 +700,10 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
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;
@ -712,8 +712,7 @@ bool GrClipMaskManager::CreateStencilClipMask(GrContext* context,
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);
@ -775,8 +774,8 @@ sk_sp<GrTexture> GrClipMaskManager::CreateSoftwareClipMask(
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;
}
@ -787,7 +786,8 @@ sk_sp<GrTexture> GrClipMaskManager::CreateSoftwareClipMask(
} 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);
}
}

View File

@ -925,11 +925,11 @@ bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
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;
@ -951,8 +951,7 @@ bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
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);
@ -962,11 +961,11 @@ bool GrDrawContextPriv::drawAndStencilPath(const GrFixedClip& clip,
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;
@ -976,14 +975,11 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
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;
@ -992,55 +988,26 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
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);
shape = shape.applyStyle(GrStyle::Apply::kPathEffectOnly, styleScale);
if (shape.isEmpty()) {
return;
}
tmpStyle.init(rec, nullptr);
canDrawArgs.fPath = tmpPath.get();
canDrawArgs.fStyle = tmpStyle.get();
if (canDrawArgs.fPath->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
@ -1055,8 +1022,7 @@ void GrDrawContext::internalDrawPath(const GrClip& clip,
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);

View File

@ -11,7 +11,7 @@
#include "GrDrawContext.h"
#include "GrPaint.h"
#include "GrResourceProvider.h"
#include "GrStyle.h"
#include "GrShape.h"
#include "SkDrawProcs.h"
#include "SkTArray.h"
@ -60,11 +60,15 @@ public:
* 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()
@ -72,28 +76,26 @@ public:
* 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
};
/**
@ -117,8 +119,7 @@ public:
* 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.
*/
@ -131,11 +132,10 @@ public:
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);
@ -143,10 +143,9 @@ public:
SkASSERT(fDrawContext);
SkASSERT(fClip);
SkASSERT(fViewMatrix);
SkASSERT(fPath);
SkASSERT(fStyle);
SkASSERT(!fPath->isEmpty());
SkASSERT(fShape);
}
#endif
};
/**
@ -159,16 +158,17 @@ public:
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);
@ -187,16 +187,21 @@ public:
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
};
/**
@ -205,7 +210,7 @@ public:
*/
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);
}
@ -240,7 +245,7 @@ private:
/**
* 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;
}
@ -278,8 +283,7 @@ private:
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);

View File

@ -79,7 +79,7 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(
}
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;
}
}
@ -87,8 +87,7 @@ GrPathRenderer* GrPathRendererChain::getPathRenderer(
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) {

View File

@ -11,13 +11,10 @@
#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"
@ -55,13 +52,15 @@ void GrSWMaskHelper::drawRect(const SkRect& rect, SkRegion::Op op,
/**
* 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);
@ -132,23 +131,21 @@ void GrSWMaskHelper::toSDF(unsigned char* sdf) {
////////////////////////////////////////////////////////////////////////////////
/**
* 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) {
@ -160,14 +157,14 @@ GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrTextureProvider* texProvider,
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;

View File

@ -19,11 +19,10 @@
class GrClip;
class GrPaint;
class GrShape;
class GrTextureProvider;
class GrStyle;
class GrTexture;
class SkPath;
class SkStrokeRec;
struct GrUserStencilSettings;
/**
@ -54,8 +53,7 @@ public:
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);
@ -70,14 +68,13 @@ public:
// 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);
static GrTexture* DrawShapeMaskToTexture(GrTextureProvider*,
const GrShape&,
const SkIRect& resultBounds,
bool antiAlias,
const SkMatrix* matrix);
// This utility routine is used to add a path's mask to some other draw.
// 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
@ -87,14 +84,14 @@ public:
// 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

View File

@ -14,7 +14,9 @@
////////////////////////////////////////////////////////////////////////////////
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 {
@ -23,33 +25,34 @@ 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;
@ -125,35 +128,41 @@ bool GrSoftwarePathRenderer::onDrawPath(const DrawPathArgs& args) {
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;

View File

@ -37,7 +37,7 @@ private:
const SkIRect& devClipBounds,
const SkIRect& devPathBounds);
StencilSupport onGetStencilSupport(const SkPath&) const override {
StencilSupport onGetStencilSupport(const GrShape&) const override {
return GrPathRenderer::kNoSupport_StencilSupport;
}

View File

@ -113,6 +113,13 @@ public:
/** 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()); }

View File

@ -681,8 +681,8 @@ sk_sp<GrGeometryProcessor> QuadEdgeEffect::TestCreate(GrProcessorTestData* d) {
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
@ -998,15 +998,12 @@ bool GrAAConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
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));

View File

@ -82,13 +82,13 @@ GrAADistanceFieldPathRenderer::~GrAADistanceFieldPathRenderer() {
////////////////////////////////////////////////////////////////////////////////
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;
}
@ -102,7 +102,7 @@ bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c
// 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;
@ -532,9 +532,7 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
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,
@ -547,19 +545,19 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) {
}
}
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,

View File

@ -23,7 +23,7 @@ public:
virtual ~GrAADistanceFieldPathRenderer();
private:
StencilSupport onGetStencilSupport(const SkPath&) const override {
StencilSupport onGetStencilSupport(const GrShape&) const override {
return GrPathRenderer::kNoSupport_StencilSupport;
}

View File

@ -618,19 +618,20 @@ bool GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const
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;
}
@ -971,12 +972,13 @@ bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
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;

View File

@ -40,23 +40,23 @@ bool GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& arg
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;
@ -324,18 +324,17 @@ bool GrAALinearizingConvexPathRenderer::onDrawPath(const DrawPathArgs& args) {
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));

View File

@ -13,8 +13,8 @@
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;
}
@ -34,12 +34,12 @@ bool GrDashLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
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;
}

View File

@ -14,7 +14,7 @@ class GrDashLinePathRenderer : public GrPathRenderer {
private:
bool onCanDrawPath(const CanDrawPathArgs&) const override;
StencilSupport onGetStencilSupport(const SkPath&) const override {
StencilSupport onGetStencilSupport(const GrShape&) const override {
return kNoSupport_StencilSupport;
}

View File

@ -34,20 +34,20 @@ GrDefaultPathRenderer::GrDefaultPathRenderer(bool separateStencilSupport,
#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;
@ -422,20 +422,19 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext,
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;
@ -454,7 +453,7 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext,
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;
@ -600,9 +599,8 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawContext* drawContext,
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) {
@ -614,30 +612,21 @@ 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);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -22,7 +22,7 @@ public:
private:
StencilSupport onGetStencilSupport(const SkPath&) const override;
StencilSupport onGetStencilSupport(const GrShape&) const override;
bool onCanDrawPath(const CanDrawPathArgs&) const override;
@ -36,8 +36,7 @@ private:
const GrClip&,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrStyle&,
const GrShape&,
bool stencilOnly);
bool fSeparateStencil;

View File

@ -31,16 +31,15 @@ static const float kTolerance = 0.5f;
////////////////////////////////////////////////////////////////////////////////
// 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;
@ -574,15 +573,19 @@ bool GrMSAAPathRenderer::internalDrawPath(GrDrawContext* drawContext,
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;
@ -709,28 +712,19 @@ bool GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
// 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,
@ -738,28 +732,22 @@ bool GrMSAAPathRenderer::onDrawPath(const DrawPathArgs& args) {
*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);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -13,7 +13,7 @@
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;
@ -27,7 +27,7 @@ private:
const GrClip&,
GrColor,
const SkMatrix& viewMatrix,
const SkPath&,
const GrShape&,
bool stencilOnly);
typedef GrPathRenderer INHERITED;

View File

@ -777,9 +777,11 @@ private:
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 {
@ -974,15 +976,13 @@ private:
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));

View File

@ -33,9 +33,8 @@ GrStencilAndCoverPathRenderer::GrStencilAndCoverPathRenderer(GrResourceProvider*
}
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) {
@ -70,6 +69,8 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
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());
@ -77,24 +78,23 @@ void GrStencilAndCoverPathRenderer::onStencilPath(const StencilPathArgs& args) {
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(

View File

@ -24,7 +24,7 @@ public:
private:
StencilSupport onGetStencilSupport(const SkPath&) const override {
StencilSupport onGetStencilSupport(const GrShape&) const override {
return GrPathRenderer::kStencilOnly_StencilSupport;
}

View File

@ -109,9 +109,10 @@ bool GrTessellatingPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) cons
// 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 {
@ -292,8 +293,11 @@ bool GrTessellatingPathRenderer::onDrawPath(const DrawPathArgs& args) {
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));

View File

@ -21,7 +21,7 @@ public:
private:
bool onCanDrawPath(const CanDrawPathArgs& ) const override;
StencilSupport onGetStencilSupport(const SkPath&) const override {
StencilSupport onGetStencilSupport(const GrShape&) const override {
return GrPathRenderer::kNoSupport_StencilSupport;
}

View File

@ -248,8 +248,8 @@ static void test_path(GrDrawContext* drawContext, GrResourceProvider* rp, const
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);
}