Replace GrAAType with flags for path renderers
Replaces the single GrAAType with a set of flags indicating which AA
types are acceptable for the path renderer to use.
Bug: skia:
Change-Id: I773565c904a360355e771966b6cddba697e1165f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/200840
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index bb45932..294649c 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -654,7 +654,7 @@
GrPathRenderer::CanDrawPath
GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
if (args.fCaps->shaderCaps()->shaderDerivativeSupport() &&
- (GrAAType::kCoverage == args.fAAType) && args.fShape->style().isSimpleFill() &&
+ (AATypeFlags::kCoverage & args.fAATypeFlags) && args.fShape->style().isSimpleFill() &&
!args.fShape->inverseFilled() && args.fShape->knownToBeConvex()) {
return CanDrawPath::kYes;
}
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index b97e578..46a32fe 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -713,7 +713,7 @@
GrPathRenderer::CanDrawPath
GrAAHairLinePathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- if (GrAAType::kCoverage != args.fAAType) {
+ if (!(AATypeFlags::kCoverage & args.fAATypeFlags)) {
return CanDrawPath::kNo;
}
diff --git a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
index 74a5572..22dc05a 100644
--- a/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAALinearizingConvexPathRenderer.cpp
@@ -39,7 +39,7 @@
GrPathRenderer::CanDrawPath
GrAALinearizingConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- if (GrAAType::kCoverage != args.fAAType) {
+ if (!(AATypeFlags::kCoverage & args.fAATypeFlags)) {
return CanDrawPath::kNo;
}
if (!args.fShape->knownToBeConvex()) {
diff --git a/src/gpu/ops/GrDashLinePathRenderer.cpp b/src/gpu/ops/GrDashLinePathRenderer.cpp
index 5e9b369..6bd8441 100644
--- a/src/gpu/ops/GrDashLinePathRenderer.cpp
+++ b/src/gpu/ops/GrDashLinePathRenderer.cpp
@@ -18,7 +18,7 @@
SkPoint pts[2];
bool inverted;
if (args.fShape->style().isDashed() && args.fShape->asLine(pts, &inverted)) {
- if (args.fAAType == GrAAType::kMixedSamples) {
+ if (args.fAATypeFlags == AATypeFlags::kMixedSampledStencilThenCover) {
return CanDrawPath::kNo;
}
// We should never have an inverse dashed case.
@@ -35,18 +35,15 @@
GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
"GrDashLinePathRenderer::onDrawPath");
GrDashOp::AAMode aaMode = GrDashOp::AAMode::kNone;
- switch (args.fAAType) {
- case GrAAType::kNone:
- break;
- case GrAAType::kCoverage:
- case GrAAType::kMixedSamples:
- aaMode = GrDashOp::AAMode::kCoverage;
- break;
- case GrAAType::kMSAA:
+ if (AATypeFlags::kNone != args.fAATypeFlags) {
+ if (AATypeFlags::kMSAA & args.fAATypeFlags) {
// In this mode we will use aa between dashes but the outer border uses MSAA. Otherwise,
// we can wind up with external edges antialiased and internal edges unantialiased.
aaMode = GrDashOp::AAMode::kCoverageWithMSAA;
- break;
+ } else {
+ SkASSERT(AATypeFlags::kCoverage & args.fAATypeFlags);
+ aaMode = GrDashOp::AAMode::kCoverage;
+ }
}
SkPoint pts[2];
SkAssertResult(args.fShape->asLine(pts, nullptr));
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index 04444d0..6eb257b 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -637,15 +637,19 @@
GrPathRenderer::CanDrawPath
GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- bool isHairline = IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr);
+ bool isHairline = IsStrokeHairlineOrEquivalent(
+ args.fShape->style(), *args.fViewMatrix, nullptr);
// If we aren't a single_pass_shape or hairline, we require stencil buffers.
if (!(single_pass_shape(*args.fShape) || isHairline) &&
(args.fCaps->avoidStencilBuffers() || args.fTargetIsWrappedVkSecondaryCB)) {
return CanDrawPath::kNo;
}
- // This can draw any path with any simple fill style but doesn't do coverage-based antialiasing.
- if (GrAAType::kCoverage == args.fAAType ||
- (!args.fShape->style().isSimpleFill() && !isHairline)) {
+ // If antialiasing is required, we only support MSAA.
+ if (AATypeFlags::kNone != args.fAATypeFlags && !(AATypeFlags::kMSAA & args.fAATypeFlags)) {
+ return CanDrawPath::kNo;
+ }
+ // This can draw any path with any simple fill style.
+ if (!args.fShape->style().isSimpleFill() && !isHairline) {
return CanDrawPath::kNo;
}
// This is the fallback renderer for when a path is too complicated for the others to draw.
@@ -655,14 +659,13 @@
bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
"GrDefaultPathRenderer::onDrawPath");
- return this->internalDrawPath(args.fRenderTargetContext,
- std::move(args.fPaint),
- args.fAAType,
- *args.fUserStencilSettings,
- *args.fClip,
- *args.fViewMatrix,
- *args.fShape,
- false);
+ GrAAType aaType = (AATypeFlags::kNone != args.fAATypeFlags)
+ ? GrAAType::kMSAA
+ : GrAAType::kNone;
+
+ return this->internalDrawPath(
+ args.fRenderTargetContext, std::move(args.fPaint), aaType, *args.fUserStencilSettings,
+ *args.fClip, *args.fViewMatrix, *args.fShape, false);
}
void GrDefaultPathRenderer::onStencilPath(const StencilPathArgs& args) {
@@ -673,9 +676,11 @@
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Get());
- this->internalDrawPath(args.fRenderTargetContext, std::move(paint), args.fAAType,
- GrUserStencilSettings::kUnused, *args.fClip, *args.fViewMatrix,
- *args.fShape, true);
+ auto aaType = (GrAA::kYes == args.fDoStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone;
+
+ this->internalDrawPath(
+ args.fRenderTargetContext, std::move(paint), aaType, GrUserStencilSettings::kUnused,
+ *args.fClip, *args.fViewMatrix, *args.fShape, true);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/ops/GrDrawPathOp.cpp b/src/gpu/ops/GrDrawPathOp.cpp
index f73bbbe..acbcf94 100644
--- a/src/gpu/ops/GrDrawPathOp.cpp
+++ b/src/gpu/ops/GrDrawPathOp.cpp
@@ -25,12 +25,12 @@
};
GrDrawPathOpBase::GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&& paint,
- GrPathRendering::FillType fill, GrAAType aaType)
+ GrPathRendering::FillType fill, GrAA aa)
: INHERITED(classID)
, fViewMatrix(viewMatrix)
, fInputColor(paint.getColor4f())
, fFillType(fill)
- , fAAType(aaType)
+ , fDoAA(GrAA::kYes == aa)
, fProcessorSet(std::move(paint)) {}
#ifdef SK_DEBUG
@@ -44,7 +44,7 @@
GrPipeline::InitArgs GrDrawPathOpBase::pipelineInitArgs(const GrOpFlushState& state) {
GrPipeline::InitArgs args;
- if (GrAATypeIsHW(fAAType)) {
+ if (fDoAA) {
args.fFlags |= GrPipeline::kHWAntialias_Flag;
}
args.fUserStencil = &kCoverPass;
@@ -77,11 +77,11 @@
std::unique_ptr<GrDrawOp> GrDrawPathOp::Make(GrRecordingContext* context,
const SkMatrix& viewMatrix,
GrPaint&& paint,
- GrAAType aaType,
+ GrAA aa,
GrPath* path) {
GrOpMemoryPool* pool = context->priv().opMemoryPool();
- return pool->allocate<GrDrawPathOp>(viewMatrix, std::move(paint), aaType, path);
+ return pool->allocate<GrDrawPathOp>(viewMatrix, std::move(paint), aa, path);
}
void GrDrawPathOp::onExecute(GrOpFlushState* state, const SkRect& chainBounds) {
diff --git a/src/gpu/ops/GrDrawPathOp.h b/src/gpu/ops/GrDrawPathOp.h
index 89a294f..d2447bb 100644
--- a/src/gpu/ops/GrDrawPathOp.h
+++ b/src/gpu/ops/GrDrawPathOp.h
@@ -22,13 +22,12 @@
class GrDrawPathOpBase : public GrDrawOp {
protected:
GrDrawPathOpBase(uint32_t classID, const SkMatrix& viewMatrix, GrPaint&&,
- GrPathRendering::FillType, GrAAType);
+ GrPathRendering::FillType, GrAA);
FixedFunctionFlags fixedFunctionFlags() const override {
- if (GrAATypeIsHW(fAAType)) {
- return FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil;
- }
- return FixedFunctionFlags::kUsesStencil;
+ return (fDoAA)
+ ? FixedFunctionFlags::kUsesHWAA | FixedFunctionFlags::kUsesStencil
+ : FixedFunctionFlags::kUsesStencil;
}
GrProcessorSet::Analysis finalize(
const GrCaps& caps, const GrAppliedClip* clip, GrFSAAType fsaaType) override {
@@ -60,7 +59,7 @@
SkPMColor4f fInputColor;
GrProcessorSet::Analysis fAnalysis;
GrPathRendering::FillType fFillType;
- GrAAType fAAType;
+ bool fDoAA;
GrProcessorSet fProcessorSet;
typedef GrDrawOp INHERITED;
@@ -70,11 +69,8 @@
public:
DEFINE_OP_CLASS_ID
- static std::unique_ptr<GrDrawOp> Make(GrRecordingContext*,
- const SkMatrix& viewMatrix,
- GrPaint&&,
- GrAAType,
- GrPath*);
+ static std::unique_ptr<GrDrawOp> Make(
+ GrRecordingContext*, const SkMatrix& viewMatrix, GrPaint&&, GrAA, GrPath*);
const char* name() const override { return "DrawPath"; }
@@ -85,8 +81,9 @@
private:
friend class GrOpMemoryPool; // for ctor
- GrDrawPathOp(const SkMatrix& viewMatrix, GrPaint&& paint, GrAAType aaType, const GrPath* path)
- : GrDrawPathOpBase(ClassID(), viewMatrix, std::move(paint), path->getFillType(), aaType)
+ GrDrawPathOp(const SkMatrix& viewMatrix, GrPaint&& paint, GrAA aa, const GrPath* path)
+ : GrDrawPathOpBase(
+ ClassID(), viewMatrix, std::move(paint), path->getFillType(), aa)
, fPath(path) {
this->setTransformedBounds(path->getBounds(), viewMatrix, HasAABloat::kNo, IsZeroArea::kNo);
}
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index e04c307..f7b1af3 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -188,7 +188,7 @@
return CanDrawPath::kNo;
}
// This does non-inverse coverage-based antialiased fills.
- if (GrAAType::kCoverage != args.fAAType) {
+ if (!(AATypeFlags::kCoverage & args.fAATypeFlags)) {
return CanDrawPath::kNo;
}
// TODO: Support inverse fill
diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
index 68782d3..1da8fa5 100644
--- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
@@ -46,7 +46,7 @@
return CanDrawPath::kNo;
}
// doesn't do per-path AA, relies on the target having MSAA.
- if (GrAAType::kCoverage == args.fAAType) {
+ if (AATypeFlags::kCoverage == args.fAATypeFlags) {
return CanDrawPath::kNo;
}
return CanDrawPath::kYes;
@@ -81,8 +81,8 @@
GR_AUDIT_TRAIL_AUTO_FRAME(args.fRenderTargetContext->auditTrail(),
"GrStencilAndCoverPathRenderer::onStencilPath");
sk_sp<GrPath> p(get_gr_path(fResourceProvider, *args.fShape));
- args.fRenderTargetContext->priv().stencilPath(*args.fClip, args.fAAType,
- *args.fViewMatrix, p.get());
+ args.fRenderTargetContext->priv().stencilPath(
+ *args.fClip, args.fDoStencilMSAA, *args.fViewMatrix, p.get());
}
bool GrStencilAndCoverPathRenderer::onDrawPath(const DrawPathArgs& args) {
@@ -92,6 +92,9 @@
const SkMatrix& viewMatrix = *args.fViewMatrix;
+ bool doStencilMSAA = AATypeFlags::kNone != args.fAATypeFlags;
+ SkASSERT(!doStencilMSAA ||
+ (AATypeFlags::kMSAA | AATypeFlags::kMixedSampledStencilThenCover) & args.fAATypeFlags);
sk_sp<GrPath> path(get_gr_path(fResourceProvider, *args.fShape));
@@ -106,8 +109,9 @@
// fake inverse with a stencil and cover
GrAppliedClip appliedClip;
- if (!args.fClip->apply(args.fContext, args.fRenderTargetContext,
- GrAATypeIsHW(args.fAAType), true, &appliedClip, &devBounds)) {
+ if (!args.fClip->apply(
+ args.fContext, args.fRenderTargetContext, doStencilMSAA, true, &appliedClip,
+ &devBounds)) {
return true;
}
GrStencilClip stencilClip(appliedClip.stencilStackID());
@@ -120,8 +124,8 @@
}
// Just ignore the analytic FPs (if any) during the stencil pass. They will still clip the
// final draw and it is meaningless to multiply by coverage when drawing to stencil.
- args.fRenderTargetContext->priv().stencilPath(stencilClip, args.fAAType, viewMatrix,
- path.get());
+ args.fRenderTargetContext->priv().stencilPath(
+ stencilClip, GrAA(doStencilMSAA), viewMatrix, path.get());
{
static constexpr GrUserStencilSettings kInvertedCoverPass(
@@ -153,23 +157,22 @@
// We have to suppress enabling MSAA for mixed samples or we will get seams due to
// coverage modulation along the edge where two triangles making up the rect meet.
- GrAAType coverAAType = args.fAAType;
- if (GrAAType::kMixedSamples == coverAAType) {
- coverAAType = GrAAType::kNone;
+ GrAAType coverAAType = GrAAType::kNone;
+ if (AATypeFlags::kMSAA & args.fAATypeFlags) {
+ SkASSERT(!(AATypeFlags::kMixedSampledStencilThenCover & args.fAATypeFlags));
+ coverAAType = GrAAType::kMSAA;
}
// This is a non-coverage aa rect operation
SkASSERT(coverAAType == GrAAType::kNone || coverAAType == GrAAType::kMSAA);
std::unique_ptr<GrDrawOp> op = GrFillRectOp::MakeWithLocalMatrix(
- args.fContext, std::move(args.fPaint),
- coverAAType, coverMatrix, localMatrix,
- coverBounds, &kInvertedCoverPass);
+ args.fContext, std::move(args.fPaint), coverAAType, coverMatrix, localMatrix,
+ coverBounds, &kInvertedCoverPass);
args.fRenderTargetContext->addDrawOp(*args.fClip, std::move(op));
}
} else {
- std::unique_ptr<GrDrawOp> op =
- GrDrawPathOp::Make(args.fContext, viewMatrix, std::move(args.fPaint),
- args.fAAType, path.get());
+ std::unique_ptr<GrDrawOp> op = GrDrawPathOp::Make(
+ args.fContext, viewMatrix, std::move(args.fPaint), GrAA(doStencilMSAA), path.get());
args.fRenderTargetContext->addDrawOp(*args.fClip, std::move(op));
}
diff --git a/src/gpu/ops/GrTessellatingPathRenderer.cpp b/src/gpu/ops/GrTessellatingPathRenderer.cpp
index 09f09ad..41ec465 100644
--- a/src/gpu/ops/GrTessellatingPathRenderer.cpp
+++ b/src/gpu/ops/GrTessellatingPathRenderer.cpp
@@ -145,21 +145,25 @@
// This path renderer can draw fill styles, and can do screenspace antialiasing via a
// one-pixel coverage ramp. It can do convex and concave paths, but we'll leave the convex
// ones to simpler algorithms. We pass on paths that have styles, though they may come back
- // around after applying the styling information to the geometry to create a filled path. In
- // the non-AA case, We skip paths that don't have a key since the real advantage of this path
- // renderer comes from caching the tessellated geometry. In the AA case, we do not cache, so we
- // accept paths without keys.
+ // around after applying the styling information to the geometry to create a filled path.
if (!args.fShape->style().isSimpleFill() || args.fShape->knownToBeConvex()) {
return CanDrawPath::kNo;
}
- if (GrAAType::kCoverage == args.fAAType) {
+ if (AATypeFlags::kNone == args.fAATypeFlags || (AATypeFlags::kMSAA & args.fAATypeFlags)) {
+ // Prefer MSAA, if any antialiasing. In the non-analytic-AA case, We skip paths that don't
+ // have a key since the real advantage of this path renderer comes from caching the
+ // tessellated geometry.
+ if (!args.fShape->hasUnstyledKey()) {
+ return CanDrawPath::kNo;
+ }
+ } else if (AATypeFlags::kCoverage & args.fAATypeFlags) {
+ // Use analytic AA if we don't have MSAA. In this case, we do not cache, so we accept paths
+ // without keys.
SkPath path;
args.fShape->asPath(&path);
if (path.countVerbs() > GR_AA_TESSELLATOR_MAX_VERB_COUNT) {
return CanDrawPath::kNo;
}
- } else if (!args.fShape->hasUnstyledKey()) {
- return CanDrawPath::kNo;
}
return CanDrawPath::kYes;
}
@@ -390,13 +394,15 @@
args.fClip->getConservativeBounds(args.fRenderTargetContext->width(),
args.fRenderTargetContext->height(),
&clipBoundsI);
- std::unique_ptr<GrDrawOp> op = TessellatingPathOp::Make(args.fContext,
- std::move(args.fPaint),
- *args.fShape,
- *args.fViewMatrix,
- clipBoundsI,
- args.fAAType,
- args.fUserStencilSettings);
+ GrAAType aaType = GrAAType::kNone;
+ if (AATypeFlags::kMSAA & args.fAATypeFlags) {
+ aaType = GrAAType::kMSAA;
+ } else if (AATypeFlags::kCoverage & args.fAATypeFlags) {
+ aaType = GrAAType::kCoverage;
+ }
+ std::unique_ptr<GrDrawOp> op = TessellatingPathOp::Make(
+ args.fContext, std::move(args.fPaint), *args.fShape, *args.fViewMatrix, clipBoundsI,
+ aaType, args.fUserStencilSettings);
args.fRenderTargetContext->addDrawOp(*args.fClip, std::move(op));
return true;
}