Add flag to avoid stencil buffers in Skia
Certain systems experience a leak in the GL driver associated with
stencil buffers. Attempts to avoid the leak (while still using stencil
buffers) dind't succeed. This patch adds a GrContextOption
fAvoidStencilBuffers. This disables certain path rendering modes, as
well as stencil based masking/clipping.
Bug: 713854
Change-Id: Ifa6c0f2bd5ee395547bda9165d6c79d197ae8b8b
Reviewed-on: https://skia-review.googlesource.com/15253
Commit-Queue: Eric Karl <ericrk@chromium.org>
Reviewed-by: Eric Karl <ericrk@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/ops/GrAAConvexPathRenderer.cpp b/src/gpu/ops/GrAAConvexPathRenderer.cpp
index f9e95c7..9144d16 100644
--- a/src/gpu/ops/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/ops/GrAAConvexPathRenderer.cpp
@@ -667,9 +667,9 @@
///////////////////////////////////////////////////////////////////////////////
bool GrAAConvexPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- return (args.fShaderCaps->shaderDerivativeSupport() && (GrAAType::kCoverage == args.fAAType) &&
- args.fShape->style().isSimpleFill() && !args.fShape->inverseFilled() &&
- args.fShape->knownToBeConvex());
+ return (args.fCaps->shaderCaps()->shaderDerivativeSupport() &&
+ (GrAAType::kCoverage == args.fAAType) && args.fShape->style().isSimpleFill() &&
+ !args.fShape->inverseFilled() && args.fShape->knownToBeConvex());
}
// extract the result vertices and indices from the GrAAConvexTessellator
diff --git a/src/gpu/ops/GrAAHairLinePathRenderer.cpp b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
index b8ec966..a40f059 100644
--- a/src/gpu/ops/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/ops/GrAAHairLinePathRenderer.cpp
@@ -624,7 +624,7 @@
}
if (SkPath::kLine_SegmentMask == args.fShape->segmentMask() ||
- args.fShaderCaps->shaderDerivativeSupport()) {
+ args.fCaps->shaderCaps()->shaderDerivativeSupport()) {
return true;
}
diff --git a/src/gpu/ops/GrDefaultPathRenderer.cpp b/src/gpu/ops/GrDefaultPathRenderer.cpp
index 0ec090e..ef925b6 100644
--- a/src/gpu/ops/GrDefaultPathRenderer.cpp
+++ b/src/gpu/ops/GrDefaultPathRenderer.cpp
@@ -548,10 +548,14 @@
}
bool GrDefaultPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
+ 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()) {
+ return false;
+ }
// This can draw any path with any simple fill style but doesn't do coverage-based antialiasing.
return GrAAType::kCoverage != args.fAAType &&
- (args.fShape->style().isSimpleFill() ||
- IsStrokeHairlineOrEquivalent(args.fShape->style(), *args.fViewMatrix, nullptr));
+ (args.fShape->style().isSimpleFill() || isHairline);
}
bool GrDefaultPathRenderer::onDrawPath(const DrawPathArgs& args) {
diff --git a/src/gpu/ops/GrMSAAPathRenderer.cpp b/src/gpu/ops/GrMSAAPathRenderer.cpp
index d4c0f3f..b2782df 100644
--- a/src/gpu/ops/GrMSAAPathRenderer.cpp
+++ b/src/gpu/ops/GrMSAAPathRenderer.cpp
@@ -677,6 +677,10 @@
}
bool GrMSAAPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
+ // If we aren't a single_pass_shape, we require stencil buffers.
+ if (!single_pass_shape(*args.fShape) && args.fCaps->avoidStencilBuffers()) {
+ return false;
+ }
// This path renderer only fills and relies on MSAA for antialiasing. Stroked shapes are
// handled by passing on the original shape and letting the caller compute the stroked shape
// which will have a fill style.
diff --git a/src/gpu/ops/GrSmallPathRenderer.cpp b/src/gpu/ops/GrSmallPathRenderer.cpp
index 53de779..7b937e5 100644
--- a/src/gpu/ops/GrSmallPathRenderer.cpp
+++ b/src/gpu/ops/GrSmallPathRenderer.cpp
@@ -87,7 +87,7 @@
////////////////////////////////////////////////////////////////////////////////
bool GrSmallPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) const {
- if (!args.fShaderCaps->shaderDerivativeSupport()) {
+ if (!args.fCaps->shaderCaps()->shaderDerivativeSupport()) {
return false;
}
// If the shape has no key then we won't get any reuse.
diff --git a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
index bd5c297..9832359 100644
--- a/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/ops/GrStencilAndCoverPathRenderer.cpp
@@ -22,7 +22,7 @@
GrPathRenderer* GrStencilAndCoverPathRenderer::Create(GrResourceProvider* resourceProvider,
const GrCaps& caps) {
- if (caps.shaderCaps()->pathRenderingSupport()) {
+ if (caps.shaderCaps()->pathRenderingSupport() && !caps.avoidStencilBuffers()) {
return new GrStencilAndCoverPathRenderer(resourceProvider);
} else {
return nullptr;