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/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index a840bf5..dd31406 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -114,6 +114,12 @@
path.toggleInverseFillType();
}
+ // We only use this method when rendering coverage clip masks.
+ SkASSERT(GrFSAAType::kNone == renderTargetContext->fsaaType());
+ auto aaTypeFlags = (element->isAA())
+ ? GrPathRenderer::AATypeFlags::kCoverage
+ : GrPathRenderer::AATypeFlags::kNone;
+
GrPathRendererChain::DrawType type =
needsStencil ? GrPathRendererChain::DrawType::kStencilAndColor
: GrPathRendererChain::DrawType::kColor;
@@ -124,10 +130,7 @@
canDrawArgs.fClipConservativeBounds = &scissorRect;
canDrawArgs.fViewMatrix = &viewMatrix;
canDrawArgs.fShape = &shape;
- canDrawArgs.fAAType = GrChooseAAType(GrAA(element->isAA()),
- renderTargetContext->fsaaType(),
- GrAllowMixedSamples::kYes,
- *context->priv().caps());
+ canDrawArgs.fAATypeFlags = aaTypeFlags;
SkASSERT(!renderTargetContext->wrapsVkSecondaryCB());
canDrawArgs.fTargetIsWrappedVkSecondaryCB = false;
canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
diff --git a/src/gpu/GrPathRenderer.cpp b/src/gpu/GrPathRenderer.cpp
index 83e8b5b..1595207 100644
--- a/src/gpu/GrPathRenderer.cpp
+++ b/src/gpu/GrPathRenderer.cpp
@@ -22,7 +22,6 @@
SkASSERT(fViewMatrix);
SkASSERT(fShape);
SkASSERT(fShape->style().isSimpleFill());
- SkASSERT(GrAAType::kCoverage != fAAType);
SkPath path;
fShape->asPath(&path);
SkASSERT(!path.isInverseFillType());
@@ -49,15 +48,14 @@
canArgs.fClipConservativeBounds = args.fClipConservativeBounds;
canArgs.fViewMatrix = args.fViewMatrix;
canArgs.fShape = args.fShape;
- canArgs.fAAType = args.fAAType;
+ canArgs.fAATypeFlags = args.fAATypeFlags;
canArgs.fTargetIsWrappedVkSecondaryCB = args.fRenderTargetContext->wrapsVkSecondaryCB();
canArgs.validate();
canArgs.fHasUserStencilSettings = !args.fUserStencilSettings->isUnused();
- SkASSERT(!(canArgs.fAAType == GrAAType::kMSAA &&
- GrFSAAType::kUnifiedMSAA != args.fRenderTargetContext->fsaaType()));
- SkASSERT(!(canArgs.fAAType == GrAAType::kMixedSamples &&
- GrFSAAType::kMixedSamples != args.fRenderTargetContext->fsaaType()));
+ if (AATypeFlags::kMixedSampledStencilThenCover & canArgs.fAATypeFlags) {
+ SkASSERT(GrFSAAType::kMixedSamples == args.fRenderTargetContext->fsaaType());
+ }
SkASSERT(CanDrawPath::kNo != this->canDrawPath(canArgs));
if (!args.fUserStencilSettings->isUnused()) {
SkPath path;
@@ -118,7 +116,9 @@
args.fClipConservativeBounds,
args.fViewMatrix,
args.fShape,
- args.fAAType,
+ (GrAA::kYes == args.fDoStencilMSAA)
+ ? AATypeFlags::kMSAA
+ : AATypeFlags::kNone,
false};
this->drawPath(drawArgs);
}
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 7101878..aac401e 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -72,6 +72,17 @@
kYes
};
+ /**
+ * This enum defines a set of flags indicating which AA methods would be acceptable for a path
+ * renderer to employ (if any) while drawing a given path.
+ */
+ enum class AATypeFlags {
+ kNone = 0,
+ kCoverage = (1 << 0),
+ kMSAA = (1 << 1),
+ kMixedSampledStencilThenCover = (1 << 2),
+ };
+
struct CanDrawPathArgs {
SkDEBUGCODE(CanDrawPathArgs() { memset(this, 0, sizeof(*this)); }) // For validation.
@@ -79,7 +90,7 @@
const SkIRect* fClipConservativeBounds;
const SkMatrix* fViewMatrix;
const GrShape* fShape;
- GrAAType fAAType;
+ AATypeFlags fAATypeFlags;
bool fTargetIsWrappedVkSecondaryCB;
// This is only used by GrStencilAndCoverPathRenderer
@@ -114,7 +125,7 @@
const SkIRect* fClipConservativeBounds;
const SkMatrix* fViewMatrix;
const GrShape* fShape;
- GrAAType fAAType;
+ AATypeFlags fAATypeFlags;
bool fGammaCorrect;
#ifdef SK_DEBUG
void validate() const {
@@ -145,8 +156,8 @@
const GrHardClip* fClip;
const SkIRect* fClipConservativeBounds;
const SkMatrix* fViewMatrix;
- GrAAType fAAType;
const GrShape* fShape;
+ GrAA fDoStencilMSAA;
SkDEBUGCODE(void validate() const);
};
@@ -202,4 +213,6 @@
typedef SkRefCnt INHERITED;
};
+GR_MAKE_BITFIELD_CLASS_OPS(GrPathRenderer::AATypeFlags);
+
#endif
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 2624d86..74bd2d5 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -824,12 +824,13 @@
// walk through each clip element and perform its set op with the existing clip.
for (ElementList::Iter iter(fMaskElements); iter.get(); iter.next()) {
+ using AATypeFlags = GrPathRenderer::AATypeFlags;
const Element* element = iter.get();
- GrAAType aaType = GrAAType::kNone;
- if (element->isAA() && GrFSAAType::kNone != renderTargetContext->fsaaType()) {
- aaType = GrAAType::kMSAA;
- }
-
+ bool doStencilMSAA =
+ element->isAA() && GrFSAAType::kNone != renderTargetContext->fsaaType();
+ // Since we are only drawing to the stencil buffer, we can use kMSAA even if the render
+ // target is mixed sampled.
+ auto pathAATypeFlags = (doStencilMSAA) ? AATypeFlags::kMSAA : AATypeFlags::kNone;
bool fillInverted = false;
// This will be used to determine whether the clip shape can be rendered into the
@@ -856,7 +857,7 @@
canDrawArgs.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
canDrawArgs.fViewMatrix = &SkMatrix::I();
canDrawArgs.fShape = &shape;
- canDrawArgs.fAAType = aaType;
+ canDrawArgs.fAATypeFlags = pathAATypeFlags;
canDrawArgs.fHasUserStencilSettings = false;
canDrawArgs.fTargetIsWrappedVkSecondaryCB = renderTargetContext->wrapsVkSecondaryCB();
@@ -890,9 +891,9 @@
0xffff>()
);
if (Element::DeviceSpaceType::kRect == element->getDeviceSpaceType()) {
- renderTargetContext->priv().stencilRect(stencilClip.fixedClip(), &kDrawToStencil,
- aaType, SkMatrix::I(),
- element->getDeviceSpaceRect());
+ renderTargetContext->priv().stencilRect(
+ stencilClip.fixedClip(), &kDrawToStencil, GrAA(doStencilMSAA),
+ SkMatrix::I(), element->getDeviceSpaceRect());
} else {
if (!clipPath.isEmpty()) {
GrShape shape(clipPath, GrStyle::SimpleFill());
@@ -908,7 +909,7 @@
&stencilClip.fixedClip().scissorRect(),
&SkMatrix::I(),
&shape,
- aaType,
+ pathAATypeFlags,
false};
pr->drawPath(args);
} else {
@@ -918,7 +919,7 @@
args.fClip = &stencilClip.fixedClip();
args.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
args.fViewMatrix = &SkMatrix::I();
- args.fAAType = aaType;
+ args.fDoStencilMSAA = GrAA(doStencilMSAA);
args.fShape = &shape;
pr->stencilPath(args);
}
@@ -931,9 +932,9 @@
for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) {
if (drawDirectToClip) {
if (Element::DeviceSpaceType::kRect == element->getDeviceSpaceType()) {
- renderTargetContext->priv().stencilRect(stencilClip, *pass, aaType,
- SkMatrix::I(),
- element->getDeviceSpaceRect());
+ renderTargetContext->priv().stencilRect(
+ stencilClip, *pass, GrAA(doStencilMSAA), SkMatrix::I(),
+ element->getDeviceSpaceRect());
} else {
GrShape shape(clipPath, GrStyle::SimpleFill());
GrPaint paint;
@@ -946,15 +947,16 @@
&stencilClip.fixedClip().scissorRect(),
&SkMatrix::I(),
&shape,
- aaType,
+ pathAATypeFlags,
false};
pr->drawPath(args);
}
} else {
// The view matrix is setup to do clip space -> stencil space translation, so
// draw rect in clip space.
- renderTargetContext->priv().stencilRect(stencilClip, *pass, aaType, SkMatrix::I(),
- SkRect::Make(fScissor));
+ renderTargetContext->priv().stencilRect(
+ stencilClip, *pass, GrAA(doStencilMSAA), SkMatrix::I(),
+ SkRect::Make(fScissor));
}
}
}
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index a148cef..8fff430 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -142,6 +142,29 @@
return GrAAType::kNone;
}
+static inline GrPathRenderer::AATypeFlags choose_path_aa_type_flags(
+ GrAA aa, GrFSAAType fsaaType, const GrCaps& caps) {
+ using AATypeFlags = GrPathRenderer::AATypeFlags;
+ if (GrAA::kNo == aa) {
+ // On some devices we cannot disable MSAA if it is enabled so we make the AA type flags
+ // reflect that.
+ if (fsaaType == GrFSAAType::kUnifiedMSAA && !caps.multisampleDisableSupport()) {
+ return AATypeFlags::kMSAA;
+ }
+ return AATypeFlags::kNone;
+ }
+ switch (fsaaType) {
+ case GrFSAAType::kNone:
+ return AATypeFlags::kCoverage;
+ case GrFSAAType::kMixedSamples:
+ return AATypeFlags::kCoverage | AATypeFlags::kMixedSampledStencilThenCover;
+ case GrFSAAType::kUnifiedMSAA:
+ return AATypeFlags::kMSAA;
+ }
+ SK_ABORT("Invalid GrFSAAType.");
+ return AATypeFlags::kNone;
+}
+
//////////////////////////////////////////////////////////////////////////////
class AutoCheckFlush {
@@ -793,7 +816,7 @@
}
void GrRenderTargetContextPriv::stencilPath(const GrHardClip& clip,
- GrAAType aaType,
+ GrAA doStencilMSAA,
const SkMatrix& viewMatrix,
const GrPath* path) {
ASSERT_SINGLE_OWNER_PRIV
@@ -802,9 +825,6 @@
GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "stencilPath",
fRenderTargetContext->fContext);
- SkASSERT(aaType != GrAAType::kCoverage);
-
- bool useHWAA = GrAATypeIsHW(aaType);
// TODO: extract portions of checkDraw that are relevant to path stenciling.
SkASSERT(path);
SkASSERT(fRenderTargetContext->caps()->shaderCaps()->pathRenderingSupport());
@@ -824,7 +844,7 @@
std::unique_ptr<GrOp> op = GrStencilPathOp::Make(fRenderTargetContext->fContext,
viewMatrix,
- useHWAA,
+ GrAA::kYes == doStencilMSAA,
path->getFillType(),
appliedClip.hasStencilClip(),
appliedClip.scissorState(),
@@ -838,7 +858,7 @@
void GrRenderTargetContextPriv::stencilRect(const GrHardClip& clip,
const GrUserStencilSettings* ss,
- GrAAType aaType,
+ GrAA doStencilMSAA,
const SkMatrix& viewMatrix,
const SkRect& rect) {
ASSERT_SINGLE_OWNER_PRIV
@@ -847,11 +867,11 @@
GR_CREATE_TRACE_MARKER_CONTEXT("GrRenderTargetContextPriv", "stencilRect",
fRenderTargetContext->fContext);
- SkASSERT(GrAAType::kCoverage != aaType);
AutoCheckFlush acf(fRenderTargetContext->drawingManager());
GrPaint paint;
paint.setXPFactory(GrDisableColorXPFactory::Get());
+ auto aaType = (GrAA::kYes == doStencilMSAA) ? GrAAType::kMSAA : GrAAType::kNone;
std::unique_ptr<GrDrawOp> op = GrFillRectOp::Make(
fRenderTargetContext->fContext, std::move(paint), aaType, viewMatrix, rect, ss);
fRenderTargetContext->addDrawOp(clip, std::move(op));
@@ -1866,7 +1886,8 @@
// the src color (either the input alpha or in the frag shader) to implement
// aa. If we have some future driver-mojo path AA that can do the right
// thing WRT to the blend then we'll need some query on the PR.
- GrAAType aaType = fRenderTargetContext->chooseAAType(aa, GrAllowMixedSamples::kNo);
+ auto aaTypeFlags = choose_path_aa_type_flags(
+ aa, fRenderTargetContext->fsaaType(), *fRenderTargetContext->caps());
bool hasUserStencilSettings = !ss->isUnused();
SkIRect clipConservativeBounds;
@@ -1879,7 +1900,7 @@
canDrawArgs.fViewMatrix = &viewMatrix;
canDrawArgs.fShape = &shape;
canDrawArgs.fClipConservativeBounds = &clipConservativeBounds;
- canDrawArgs.fAAType = aaType;
+ canDrawArgs.fAATypeFlags = aaTypeFlags;
SkASSERT(!fRenderTargetContext->wrapsVkSecondaryCB());
canDrawArgs.fTargetIsWrappedVkSecondaryCB = false;
canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
@@ -1902,7 +1923,7 @@
&clipConservativeBounds,
&viewMatrix,
&shape,
- aaType,
+ aaTypeFlags,
fRenderTargetContext->colorSpaceInfo().isLinearlyBlended()};
pr->drawPath(args);
return true;
@@ -1937,13 +1958,8 @@
clip.getConservativeBounds(this->width(), this->height(), &clipConservativeBounds, nullptr);
GrShape tempShape;
- // NVPR cannot handle hairlines, so this would get picked up by a different stencil and
- // cover path renderer (i.e. default path renderer). The hairline renderer produces much
- // smoother hairlines than MSAA.
- GrAllowMixedSamples allowMixedSamples = originalShape.style().isSimpleHairline()
- ? GrAllowMixedSamples::kNo
- : GrAllowMixedSamples::kYes;
- GrAAType aaType = this->chooseAAType(aa, allowMixedSamples);
+ auto aaTypeFlags = choose_path_aa_type_flags(aa, this->fsaaType(), *this->caps());
+
GrPathRenderer::CanDrawPathArgs canDrawArgs;
canDrawArgs.fCaps = this->caps();
canDrawArgs.fViewMatrix = &viewMatrix;
@@ -1958,7 +1974,7 @@
return;
}
- canDrawArgs.fAAType = aaType;
+ canDrawArgs.fAATypeFlags = aaTypeFlags;
// Try a 1st time without applying any of the style to the geometry (and barring sw)
pr = this->drawingManager()->getPathRenderer(canDrawArgs, false, kType);
@@ -2003,7 +2019,7 @@
&clipConservativeBounds,
&viewMatrix,
canDrawArgs.fShape,
- aaType,
+ aaTypeFlags,
this->colorSpaceInfo().isLinearlyBlended()};
pr->drawPath(args);
}
diff --git a/src/gpu/GrRenderTargetContextPriv.h b/src/gpu/GrRenderTargetContextPriv.h
index 3e3b619..0858749 100644
--- a/src/gpu/GrRenderTargetContextPriv.h
+++ b/src/gpu/GrRenderTargetContextPriv.h
@@ -62,13 +62,12 @@
*/
void absClear(const SkIRect* rect, const SkPMColor4f& color);
- void stencilRect(const GrHardClip&,
- const GrUserStencilSettings* ss,
- GrAAType,
- const SkMatrix& viewMatrix,
- const SkRect& rect);
+ void stencilRect(
+ const GrHardClip&, const GrUserStencilSettings* ss, GrAA doStencilMSAA,
+ const SkMatrix& viewMatrix, const SkRect& rect);
- void stencilPath(const GrHardClip&, GrAAType, const SkMatrix& viewMatrix, const GrPath*);
+ void stencilPath(
+ const GrHardClip&, GrAA doStencilMSAA, const SkMatrix& viewMatrix, const GrPath*);
/**
* Draws a rect, either AA or not, and touches the stencil buffer with the user stencil settings
@@ -78,7 +77,7 @@
const GrUserStencilSettings*,
SkRegion::Op op,
bool invert,
- GrAA,
+ GrAA doStencilMSAA,
const SkMatrix& viewMatrix,
const SkRect&);
@@ -90,7 +89,7 @@
const GrUserStencilSettings*,
SkRegion::Op op,
bool invert,
- GrAA,
+ GrAA doStencilMSAA,
const SkMatrix& viewMatrix,
const SkPath&);
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 2264141..2fee0fb 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -32,7 +32,7 @@
// 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.
if (!args.fShape->style().applies() && SkToBool(fProxyProvider) &&
- (args.fAAType == GrAAType::kCoverage || args.fAAType == GrAAType::kNone)) {
+ ((args.fAATypeFlags & AATypeFlags::kCoverage) || args.fAATypeFlags == AATypeFlags::kNone)) {
// This is the fallback renderer for when a path is too complicated for the GPU ones.
return CanDrawPath::kAsBackup;
}
@@ -257,7 +257,7 @@
// To prevent overloading the cache with entries during animations we limit the cache of masks
// to cases where the matrix preserves axis alignment.
bool useCache = fAllowCaching && !inverseFilled && args.fViewMatrix->preservesAxisAlignment() &&
- args.fShape->hasUnstyledKey() && GrAAType::kCoverage == args.fAAType;
+ args.fShape->hasUnstyledKey() && (AATypeFlags::kCoverage & args.fAATypeFlags);
if (!GetShapeAndClipBounds(args.fRenderTargetContext,
*args.fClip, *args.fShape,
@@ -332,7 +332,7 @@
}
if (!proxy) {
SkBackingFit fit = useCache ? SkBackingFit::kExact : SkBackingFit::kApprox;
- GrAA aa = GrAAType::kCoverage == args.fAAType ? GrAA::kYes : GrAA::kNo;
+ GrAA aa = GrAA(SkToBool(AATypeFlags::kCoverage & args.fAATypeFlags));
SkTaskGroup* taskGroup = nullptr;
if (auto direct = args.fContext->priv().asDirectContext()) {
diff --git a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
index 077b0ec..484bd08 100644
--- a/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
+++ b/src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp
@@ -56,7 +56,7 @@
GrPathRenderer::CanDrawPath GrCoverageCountingPathRenderer::onCanDrawPath(
const CanDrawPathArgs& args) const {
const GrShape& shape = *args.fShape;
- if (GrAAType::kCoverage != args.fAAType || shape.style().hasPathEffect() ||
+ if (!(AATypeFlags::kCoverage & args.fAATypeFlags) || shape.style().hasPathEffect() ||
args.fViewMatrix->hasPerspective() || shape.inverseFilled()) {
return CanDrawPath::kNo;
}
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;
}