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:
parent
c2fde8b227
commit
8acedde597
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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()); }
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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,
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
virtual ~GrAADistanceFieldPathRenderer();
|
||||
|
||||
private:
|
||||
StencilSupport onGetStencilSupport(const SkPath&) const override {
|
||||
StencilSupport onGetStencilSupport(const GrShape&) const override {
|
||||
return GrPathRenderer::kNoSupport_StencilSupport;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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(
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
|
||||
|
||||
private:
|
||||
StencilSupport onGetStencilSupport(const SkPath&) const override {
|
||||
StencilSupport onGetStencilSupport(const GrShape&) const override {
|
||||
return GrPathRenderer::kStencilOnly_StencilSupport;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user