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:
parent
7b920446a8
commit
6ea387e7c7
@ -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();
|
||||
|
@ -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.
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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>());
|
||||
|
@ -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() &&
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user