Enable GrTessellationPathRenderer by default

Moves GrTessellationPathRenderer to the end of the chain and enables
it by default.

Also updates nvpr to not draw volatile paths. The tessellator is much
faster at these.

Bug: skia:10419
Change-Id: I97ca7d4d1dff65fc9d4040c267f9808c8c33b548
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/344377
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Chris Dalton 2020-12-17 00:25:10 -07:00 committed by Skia Commit-Bot
parent 7b920446a8
commit 6ea387e7c7
11 changed files with 50 additions and 28 deletions

View File

@ -55,7 +55,7 @@ protected:
SkPathBuilder path;
path.addArc(r, startAngle, sweepAngle);
canvas->drawPath(path.detach(), paint);
canvas->drawPath(path.detach().setIsVolatile(true), paint);
r.inset(inset, inset);
sign = -sign;
@ -260,7 +260,7 @@ DEF_SIMPLE_GM(manyarcs, canvas, 620, 330) {
html_canvas_arc(&path, 18, 15, 10, startAngle, startAngle + (sweepAngles[j] * sign),
anticlockwise, true);
path.lineTo(0, 28);
canvas->drawPath(path.detach(), paint);
canvas->drawPath(path.detach().setIsVolatile(true), paint);
canvas->translate(30, 0);
}
canvas->restore();

View File

@ -780,7 +780,7 @@ enum class GpuPathRenderers {
kAALinearizing = 1 << 6,
kSmall = 1 << 7,
kTriangulating = 1 << 8,
kDefault = ((1 << 9) - 1) & ~kTessellation // All but kTessellation.
kDefault = ((1 << 9) - 1) // All path renderers.
};
/**

View File

@ -58,6 +58,7 @@ GrCaps::GrCaps(const GrContextOptions& options) {
fShouldCollapseSrcOverToSrcWhenAble = false;
fDriverDisableCCPR = false;
fDriverDisableMSAACCPR = false;
fDisableTessellationPathRenderer = false;
fBlendEquationSupport = kBasic_BlendEquationSupport;
fAdvBlendEqDisableFlags = 0;
@ -116,6 +117,7 @@ void GrCaps::applyOptionsOverrides(const GrContextOptions& options) {
if (options.fDisableDriverCorrectnessWorkarounds) {
SkASSERT(!fDriverDisableCCPR);
SkASSERT(!fDriverDisableMSAACCPR);
SkASSERT(!fDisableTessellationPathRenderer);
SkASSERT(!fAvoidStencilBuffers);
SkASSERT(!fAvoidWritePixelsFastPath);
SkASSERT(!fRequiresManualFBBarrierAfterTessellatedStencilDraw);
@ -246,6 +248,8 @@ void GrCaps::dumpJSON(SkJSONWriter* writer) const {
writer->appendBool("Disable CCPR on current driver [workaround]", fDriverDisableCCPR);
writer->appendBool("Disable MSAA version of CCPR on current driver [workaround]",
fDriverDisableMSAACCPR);
writer->appendBool("Disable GrTessellationPathRenderer current driver [workaround]",
fDisableTessellationPathRenderer);
writer->appendBool("Clamp-to-border", fClampToBorderSupport);
writer->appendBool("Prefer VRAM Use over flushes [workaround]", fPreferVRAMUseOverFlushes);

View File

@ -381,6 +381,9 @@ public:
bool driverDisableCCPR() const { return fDriverDisableCCPR; }
bool driverDisableMSAACCPR() const { return fDriverDisableMSAACCPR; }
// Should we disable GrTessellationPathRenderer due to a faulty driver?
bool disableTessellationPathRenderer() const { return fDisableTessellationPathRenderer; }
// Returns how to sample the dst values for the passed in GrRenderTargetProxy.
GrDstSampleType getDstSampleTypeForProxy(const GrRenderTargetProxy*) const;
@ -510,6 +513,7 @@ protected:
// Driver workaround
bool fDriverDisableCCPR : 1;
bool fDriverDisableMSAACCPR : 1;
bool fDisableTessellationPathRenderer : 1;
bool fAvoidStencilBuffers : 1;
bool fAvoidWritePixelsFastPath : 1;
bool fRequiresManualFBBarrierAfterTessellatedStencilDraw : 1;

View File

@ -32,13 +32,6 @@ GrPathRendererChain::GrPathRendererChain(GrRecordingContext* context, const Opti
if (options.fGpuPathRenderers & GpuPathRenderers::kDashLine) {
fChain.push_back(sk_make_sp<GrDashLinePathRenderer>());
}
if (options.fGpuPathRenderers & GpuPathRenderers::kTessellation) {
if (GrTessellationPathRenderer::IsSupported(caps)) {
auto tess = sk_make_sp<GrTessellationPathRenderer>(context);
context->priv().addOnFlushCallbackObject(tess.get());
fChain.push_back(std::move(tess));
}
}
if (options.fGpuPathRenderers & GpuPathRenderers::kAAConvex) {
fChain.push_back(sk_make_sp<GrAAConvexPathRenderer>());
}
@ -76,6 +69,13 @@ GrPathRendererChain::GrPathRendererChain(GrRecordingContext* context, const Opti
if (options.fGpuPathRenderers & GpuPathRenderers::kTriangulating) {
fChain.push_back(sk_make_sp<GrTriangulatingPathRenderer>());
}
if (options.fGpuPathRenderers & GpuPathRenderers::kTessellation) {
if (GrTessellationPathRenderer::IsSupported(caps)) {
auto tess = sk_make_sp<GrTessellationPathRenderer>(context);
context->priv().addOnFlushCallbackObject(tess.get());
fChain.push_back(std::move(tess));
}
}
// We always include the default path renderer (as well as SW), so we can draw any path
fChain.push_back(sk_make_sp<GrDefaultPathRenderer>());

View File

@ -3982,6 +3982,14 @@ void GrGLCaps::applyDriverCorrectnessWorkarounds(const GrGLContextInfo& ctxInfo,
fDriverDisableMSAACCPR = true;
}
if (kIntel_GrGLVendor == ctxInfo.vendor() || // IntelIris640 drops draws completely.
ctxInfo.renderer() == kMaliT_GrGLRenderer || // Some curves appear flat on GalaxyS6.
ctxInfo.renderer() == kAdreno3xx_GrGLRenderer ||
ctxInfo.renderer() == kAdreno430_GrGLRenderer ||
ctxInfo.renderer() == kAdreno4xx_other_GrGLRenderer) { // We get garbage on Adreno405.
fDisableTessellationPathRenderer = true;
}
// http://skbug.com/9739
bool isNVIDIAPascal =
kNVIDIA_GrGLDriver == ctxInfo.driver() &&

View File

@ -49,7 +49,8 @@ GrStencilAndCoverPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const
// path.
if (args.fShape->style().strokeRec().isHairlineStyle() ||
args.fShape->style().hasNonDashPathEffect() ||
args.fHasUserStencilSettings) {
args.fHasUserStencilSettings ||
!args.fShape->hasUnstyledKey()) {
return CanDrawPath::kNo;
}
if (GrAAType::kCoverage == args.fAAType && !args.fProxy->canUseMixedSamples(*args.fCaps)) {

View File

@ -98,21 +98,24 @@ void GrFillCubicHullShader::emitVertexCode(Impl*, GrGLSLVertexBuilder* v, const
}
}
// Find the "turn direction" of each corner and net turn direction.
float4 dir;
float netdir = 0.0;
for (int i = 0; i < 4; ++i) {
float2 prev = P[i] - P[(i + 3) & 3], next = P[(i + 1) & 3] - P[i];
dir[i] = sign(determinant(float2x2(prev, next)));
netdir += dir[i];
}
// sk_VertexID comes in fan order. Convert to strip order.
int vertexidx = sk_VertexID;
vertexidx ^= vertexidx >> 1;
// Find the "turn direction" of each corner and net turn direction.
float vertexdir = 0;
float netdir = 0;
for (int i = 0; i < 4; ++i) {
float2 prev = P[i] - P[(i + 3) & 3], next = P[(i + 1) & 3] - P[i];
float dir = sign(determinant(float2x2(prev, next)));
if (i == vertexidx) {
vertexdir = dir;
}
netdir += dir;
}
// Remove the non-convex vertex, if any.
if (dir[vertexidx] != sign(netdir)) {
if (vertexdir != sign(netdir)) {
vertexidx = (vertexidx + 1) & 3;
}

View File

@ -1022,7 +1022,7 @@ class GrStrokeTessellateShader::IndirectImpl : public GrGLSLGeometryProcessor {
// for seaming with the previous stroke. (The double sided edge at the end will
// actually come from the section of our strip that belongs to the stroke.)
if (combinedEdgeID >= 0) {
outset = clamp(outset, (turn < 0) ? -1 : 0, (turn >= 0) ? 1 : 0);
outset = (turn < 0) ? min(outset, 0) : max(outset, 0);
}
}
combinedEdgeID = max(combinedEdgeID, 0);

View File

@ -36,7 +36,9 @@ constexpr static auto kAtlasAlgorithm = GrDynamicAtlas::RectanizerAlgorithm::kPo
constexpr static int kMaxAtlasPathHeight = 128;
bool GrTessellationPathRenderer::IsSupported(const GrCaps& caps) {
return caps.drawInstancedSupport() && caps.shaderCaps()->vertexIDSupport();
return caps.drawInstancedSupport() &&
caps.shaderCaps()->vertexIDSupport() &&
!caps.disableTessellationPathRenderer();
}
GrTessellationPathRenderer::GrTessellationPathRenderer(GrRecordingContext* rContext)
@ -313,7 +315,7 @@ bool GrTessellationPathRenderer::tryAddPathToAtlas(
// Check if the path is too large for an atlas. Since we use "minDimension" for height in the
// atlas, limiting to kMaxAtlasPathHeight^2 pixels guarantees height <= kMaxAtlasPathHeight.
if (maxDimenstion * minDimension > kMaxAtlasPathHeight * kMaxAtlasPathHeight ||
if ((uint64_t)maxDimenstion * minDimension > kMaxAtlasPathHeight * kMaxAtlasPathHeight ||
maxDimenstion > fMaxAtlasPathWidth) {
return false;
}

View File

@ -29,8 +29,8 @@ static DEFINE_bool(cc, false, "Allow coverage counting shortcuts to render paths
static DEFINE_string(pr, "",
"Set of enabled gpu path renderers. Defined as a list of: "
"[~]none [~]dashline [~]tess [~]nvpr [~]ccpr [~]aahairline [~]aaconvex "
"[~]aalinearizing [~]small [~]tri] [~]all");
"[~]none [~]dashline [~]nvpr [~]ccpr [~]aahairline [~]aaconvex [~]aalinearizing "
"[~]small [~]tri [~]tess [~]all");
static DEFINE_int(internalSamples, 4,
"Number of samples for internal draws that use MSAA or mixed samples.");
@ -46,8 +46,6 @@ static GpuPathRenderers get_named_pathrenderers_flags(const char* name) {
return GpuPathRenderers::kNone;
} else if (!strcmp(name, "dashline")) {
return GpuPathRenderers::kDashLine;
} else if (!strcmp(name, "tess")) {
return GpuPathRenderers::kTessellation;
} else if (!strcmp(name, "nvpr")) {
return GpuPathRenderers::kStencilAndCover;
} else if (!strcmp(name, "ccpr")) {
@ -62,6 +60,8 @@ static GpuPathRenderers get_named_pathrenderers_flags(const char* name) {
return GpuPathRenderers::kSmall;
} else if (!strcmp(name, "tri")) {
return GpuPathRenderers::kTriangulating;
} else if (!strcmp(name, "tess")) {
return GpuPathRenderers::kTessellation;
} else if (!strcmp(name, "default")) {
return GpuPathRenderers::kDefault;
}