Add a mustWriteToFragColor() workaround flag
Bug: skia:
Change-Id: Ifeff01125ebe5418d4632ffe2422140944e44469
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/206351
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp
index bd1f667..56dbc23 100644
--- a/src/gpu/GrShaderCaps.cpp
+++ b/src/gpu/GrShaderCaps.cpp
@@ -43,6 +43,7 @@
fEmulateAbsIntFunction = false;
fRewriteDoWhileLoops = false;
fRemovePowWithConstantExponent = false;
+ fMustWriteToFragColor = false;
fFlatInterpolationSupport = false;
fPreferFlatInterpolation = false;
fNoPerspectiveInterpolationSupport = false;
@@ -117,6 +118,7 @@
writer->appendBool("Emulate abs(int) function", fEmulateAbsIntFunction);
writer->appendBool("Rewrite do while loops", fRewriteDoWhileLoops);
writer->appendBool("Rewrite pow with constant exponent", fRemovePowWithConstantExponent);
+ writer->appendBool("Must write to sk_FragColor [workaround]", fMustWriteToFragColor);
writer->appendBool("Flat interpolation support", fFlatInterpolationSupport);
writer->appendBool("Prefer flat interpolation", fPreferFlatInterpolation);
writer->appendBool("No perspective interpolation support", fNoPerspectiveInterpolationSupport);
@@ -157,6 +159,7 @@
SkASSERT(!fEmulateAbsIntFunction);
SkASSERT(!fRewriteDoWhileLoops);
SkASSERT(!fRemovePowWithConstantExponent);
+ SkASSERT(!fMustWriteToFragColor);
}
#if GR_TEST_UTILS
fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
diff --git a/src/gpu/GrShaderCaps.h b/src/gpu/GrShaderCaps.h
index 3ebb92a..bbac42d 100644
--- a/src/gpu/GrShaderCaps.h
+++ b/src/gpu/GrShaderCaps.h
@@ -154,6 +154,10 @@
return fMustGuardDivisionEvenAfterExplicitZeroCheck;
}
+ // On Nexus 6, the GL context can get lost if a shader does not write a value to gl_FragColor.
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=445377
+ bool mustWriteToFragColor() const { return fMustWriteToFragColor; }
+
// Returns the string of an extension that must be enabled in the shader to support
// derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
// this function, the caller should check that shaderDerivativeSupport exists.
@@ -288,6 +292,7 @@
bool fEmulateAbsIntFunction : 1;
bool fRewriteDoWhileLoops : 1;
bool fRemovePowWithConstantExponent : 1;
+ bool fMustWriteToFragColor : 1;
const char* fVersionDeclString;
diff --git a/src/gpu/effects/GrDisableColorXP.cpp b/src/gpu/effects/GrDisableColorXP.cpp
index 2ff36c4..7fba0b7 100644
--- a/src/gpu/effects/GrDisableColorXP.cpp
+++ b/src/gpu/effects/GrDisableColorXP.cpp
@@ -6,6 +6,7 @@
*/
#include "effects/GrDisableColorXP.h"
+#include "GrShaderCaps.h"
#include "GrPipeline.h"
#include "GrProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
@@ -50,11 +51,14 @@
private:
void emitOutputsForBlendState(const EmitArgs& args) override {
- // This emit code should be empty. However, on the nexus 6 there is a driver bug where if
- // you do not give gl_FragColor a value, the gl context is lost and we end up drawing
- // nothing. So this fix just sets the gl_FragColor arbitrarily to 0.
- GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
- fragBuilder->codeAppendf("%s = half4(0);", args.fOutputPrimary);
+ if (args.fShaderCaps->mustWriteToFragColor()) {
+ // This emit code should be empty. However, on the nexus 6 there is a driver bug where
+ // if you do not give gl_FragColor a value, the gl context is lost and we end up drawing
+ // nothing. So this fix just sets the gl_FragColor arbitrarily to 0.
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=445377
+ GrGLSLXPFragmentBuilder* fragBuilder = args.fXPFragBuilder;
+ fragBuilder->codeAppendf("%s = half4(0);", args.fOutputPrimary);
+ }
}
void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) override {}
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 7d70e7f..bbc86fc 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -2902,6 +2902,11 @@
shaderCaps->fRemovePowWithConstantExponent = true;
}
+ if (kAdreno3xx_GrGLRenderer == ctxInfo.renderer() ||
+ kAdreno4xx_other_GrGLRenderer == ctxInfo.renderer()) {
+ shaderCaps->fMustWriteToFragColor = true;
+ }
+
// Disabling advanced blend on various platforms with major known issues. We also block Chrome
// for now until its own blacklists can be updated.
if (kAdreno430_GrGLRenderer == ctxInfo.renderer() ||