aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2017-05-25 11:34:38 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-25 16:15:07 +0000
commitac1e4964e7816de1f4977b52fa5f2f372537468b (patch)
treeaebc6f877d48d956f72908b6cd27fd290502e156
parent3fdd0bf2d90b1b82c1ac3aa982bdca600de7f4a8 (diff)
Workaround Mali static analysis bug
Comment describes it: Unless we do something to confuse their optimizer, they will (incorrectly) deduce that uniform opaque color (modulated only by a texture fetch) is always going to remain opaque. Then they skip inserting their shader based blending code, turning SrcOver into Src. Doing a max against zero is enough to squelch the optimization. Bug: skia: Change-Id: I74676cebb0b0c8d121da868dd8a88050e0cfcc0d Reviewed-on: https://skia-review.googlesource.com/17924 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
-rw-r--r--include/gpu/GrShaderCaps.h3
-rw-r--r--src/gpu/GrShaderCaps.cpp2
-rw-r--r--src/gpu/gl/GrGLCaps.cpp10
-rw-r--r--src/gpu/gl/GrGLUtil.cpp4
-rw-r--r--src/gpu/gl/GrGLUtil.h2
-rw-r--r--src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp4
6 files changed, 25 insertions, 0 deletions
diff --git a/include/gpu/GrShaderCaps.h b/include/gpu/GrShaderCaps.h
index e52bcf1c81..e5edc7ebea 100644
--- a/include/gpu/GrShaderCaps.h
+++ b/include/gpu/GrShaderCaps.h
@@ -161,6 +161,8 @@ public:
// On MacBook, geometry shaders break if they have more than one invocation.
bool mustImplementGSInvocationsWithLoop() const { return fMustImplementGSInvocationsWithLoop; }
+ bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; }
+
// 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.
@@ -289,6 +291,7 @@ private:
bool fAtan2ImplementedAsAtanYOverX : 1;
bool fRequiresLocalOutputColorForFBFetch : 1;
bool fMustImplementGSInvocationsWithLoop : 1;
+ bool fMustObfuscateUniformColor : 1;
PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
diff --git a/src/gpu/GrShaderCaps.cpp b/src/gpu/GrShaderCaps.cpp
index 9a429bb0de..cf29ab5976 100644
--- a/src/gpu/GrShaderCaps.cpp
+++ b/src/gpu/GrShaderCaps.cpp
@@ -60,6 +60,7 @@ GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
fAtan2ImplementedAsAtanYOverX = false;
fRequiresLocalOutputColorForFBFetch = false;
fMustImplementGSInvocationsWithLoop = false;
+ fMustObfuscateUniformColor = false;
fFlatInterpolationSupport = false;
fNoPerspectiveInterpolationSupport = false;
fMultisampleInterpolationSupport = false;
@@ -146,6 +147,7 @@ SkString GrShaderCaps::dump() const {
"YES" : "NO"));
r.appendf("Must implement geo shader invocations with loop : %s\n",
(fMustImplementGSInvocationsWithLoop ? "YES" : "NO"));
+ r.appendf("Must obfuscate uniform color: %s\n", (fMustObfuscateUniformColor ? "YES" : "NO"));
r.appendf("Flat interpolation support: %s\n", (fFlatInterpolationSupport ? "YES" : "NO"));
r.appendf("No perspective interpolation support: %s\n", (fNoPerspectiveInterpolationSupport ?
"YES" : "NO"));
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 9164de7539..0d1d4f6fff 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -876,6 +876,16 @@ void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) {
// term plan for this WAR is for it to eventually be baked into SkSL.
shaderCaps->fMustImplementGSInvocationsWithLoop = true;
#endif
+
+ // Newer Mali GPUs do incorrect static analysis in specific situations: If there is uniform
+ // color, and that uniform contains an opaque color, and the output of the shader is only based
+ // on that uniform plus soemthing un-trackable (like a texture read), the compiler will deduce
+ // that the shader always outputs opaque values. In that case, it appears to remove the shader
+ // based blending code it normally injects, turning SrcOver into Src. To fix this, we always
+ // insert an extra bit of math on the uniform that confuses the compiler just enough...
+ if (kMaliT_GrGLRenderer == ctxInfo.renderer()) {
+ shaderCaps->fMustObfuscateUniformColor = true;
+ }
}
bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp
index 58b5860f13..41c57eb1e1 100644
--- a/src/gpu/gl/GrGLUtil.cpp
+++ b/src/gpu/gl/GrGLUtil.cpp
@@ -326,6 +326,10 @@ GrGLRenderer GrGLGetRendererFromString(const char* rendererString) {
if (0 == strcmp("Mesa Offscreen", rendererString)) {
return kOSMesa_GrGLRenderer;
}
+ static const char kMaliTStr[] = "Mali-T";
+ if (0 == strncmp(rendererString, kMaliTStr, SK_ARRAY_COUNT(kMaliTStr) - 1)) {
+ return kMaliT_GrGLRenderer;
+ }
}
return kOther_GrGLRenderer;
}
diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h
index 25bd68175b..261a4cd22d 100644
--- a/src/gpu/gl/GrGLUtil.h
+++ b/src/gpu/gl/GrGLUtil.h
@@ -56,6 +56,8 @@ enum GrGLRenderer {
kOSMesa_GrGLRenderer,
/** Either HD 6xxx or Iris 6xxx */
kIntel6xxx_GrGLRenderer,
+ /** T-6xx, T-7xx, or T-8xx */
+ kMaliT_GrGLRenderer,
kOther_GrGLRenderer
};
diff --git a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
index f39fff2a07..d32766c3fc 100644
--- a/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
+++ b/src/gpu/glsl/GrGLSLPrimitiveProcessor.cpp
@@ -9,6 +9,7 @@
#include "GrCoordTransform.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
#include "glsl/GrGLSLUniformHandler.h"
#include "glsl/GrGLSLVertexShaderBuilder.h"
@@ -46,6 +47,9 @@ void GrGLSLPrimitiveProcessor::setupUniformColor(GrGLSLPPFragmentBuilder* fragBu
"Color",
&stagedLocalVarName);
fragBuilder->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
+ if (fragBuilder->getProgramBuilder()->shaderCaps()->mustObfuscateUniformColor()) {
+ fragBuilder->codeAppendf("%s = max(%s, vec4(0, 0, 0, 0));", outputName, outputName);
+ }
}
//////////////////////////////////////////////////////////////////////////////