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>
diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp
index 2181858..9cffcc0 100644
--- a/src/gpu/GrCaps.cpp
+++ b/src/gpu/GrCaps.cpp
@@ -58,6 +58,7 @@
fShouldCollapseSrcOverToSrcWhenAble = false;
fDriverDisableCCPR = false;
fDriverDisableMSAACCPR = false;
+ fDisableTessellationPathRenderer = false;
fBlendEquationSupport = kBasic_BlendEquationSupport;
fAdvBlendEqDisableFlags = 0;
@@ -116,6 +117,7 @@
if (options.fDisableDriverCorrectnessWorkarounds) {
SkASSERT(!fDriverDisableCCPR);
SkASSERT(!fDriverDisableMSAACCPR);
+ SkASSERT(!fDisableTessellationPathRenderer);
SkASSERT(!fAvoidStencilBuffers);
SkASSERT(!fAvoidWritePixelsFastPath);
SkASSERT(!fRequiresManualFBBarrierAfterTessellatedStencilDraw);
@@ -246,6 +248,8 @@
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);
diff --git a/src/gpu/GrCaps.h b/src/gpu/GrCaps.h
index 70be646..4a51fcd 100644
--- a/src/gpu/GrCaps.h
+++ b/src/gpu/GrCaps.h
@@ -381,6 +381,9 @@
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 @@
// Driver workaround
bool fDriverDisableCCPR : 1;
bool fDriverDisableMSAACCPR : 1;
+ bool fDisableTessellationPathRenderer : 1;
bool fAvoidStencilBuffers : 1;
bool fAvoidWritePixelsFastPath : 1;
bool fRequiresManualFBBarrierAfterTessellatedStencilDraw : 1;
diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp
index 4f5807c..62b6e8a 100644
--- a/src/gpu/GrPathRendererChain.cpp
+++ b/src/gpu/GrPathRendererChain.cpp
@@ -32,13 +32,6 @@
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 @@
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>());
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 4efaec2..7770d77 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -3982,6 +3982,14 @@
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() &&
diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
index 6a5a356..cbe0c14 100644
--- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
@@ -49,7 +49,8 @@
// 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)) {
diff --git a/src/gpu/tessellate/GrFillPathShader.cpp b/src/gpu/tessellate/GrFillPathShader.cpp
index 3cb0fcb..11c5c13 100644
--- a/src/gpu/tessellate/GrFillPathShader.cpp
+++ b/src/gpu/tessellate/GrFillPathShader.cpp
@@ -98,21 +98,24 @@
}
}
- // 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;
}
diff --git a/src/gpu/tessellate/GrStrokeTessellateShader.cpp b/src/gpu/tessellate/GrStrokeTessellateShader.cpp
index 66f2289..e10292a 100644
--- a/src/gpu/tessellate/GrStrokeTessellateShader.cpp
+++ b/src/gpu/tessellate/GrStrokeTessellateShader.cpp
@@ -1022,7 +1022,7 @@
// 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);
diff --git a/src/gpu/tessellate/GrTessellationPathRenderer.cpp b/src/gpu/tessellate/GrTessellationPathRenderer.cpp
index 5d20a30..110128a 100644
--- a/src/gpu/tessellate/GrTessellationPathRenderer.cpp
+++ b/src/gpu/tessellate/GrTessellationPathRenderer.cpp
@@ -36,7 +36,9 @@
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 @@
// 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;
}