This CL does two things. First it fixes a bug of ours where when using
a custom fbFetch variable (es 3.0 and higher), we sometimes overwrite
the out color and then attempt to use it as the dst color later. This is
fixed here by using an intermediate variable.
Secondly I've added a workaround to an andreno fbFetch where reading from
the outColor always returns the original dstColor even if we've overwritten
the value.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=
2248403003
Review-Url: https://codereview.chromium.org/
2248403003
if (kIntel_GrGLVendor == ctxInfo.vendor()) {
glslCaps->fMustForceNegatedAtanParamToFloat = true;
}
+
+ // On Adreno devices with framebuffer fetch support, there is a bug where they always return
+ // the original dst color when reading the outColor even after being written to. By using a
+ // local outColor we can work around this bug.
+ if (glslCaps->fFBFetchSupport && kQualcomm_GrGLVendor == ctxInfo.vendor()) {
+ glslCaps->fRequiresLocalOutputColorForFBFetch = true;
+ }
}
bool GrGLCaps::hasPathRenderingSupport(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) {
fCanUseAnyFunctionInShader = true;
fCanUseMinAndAbsTogether = true;
fMustForceNegatedAtanParamToFloat = false;
+ fRequiresLocalOutputColorForFBFetch = false;
fFlatInterpolationSupport = false;
fNoPerspectiveInterpolationSupport = false;
fMultisampleInterpolationSupport = false;
r.appendf("Can use min() and abs() together: %s\n", (fCanUseMinAndAbsTogether ? "YES" : "NO"));
r.appendf("Must force negated atan param to float: %s\n", (fMustForceNegatedAtanParamToFloat ?
"YES" : "NO"));
+ r.appendf("Must use local out color for FBFetch: %s\n", (fRequiresLocalOutputColorForFBFetch ?
+ "YES" : "NO"));
r.appendf("Flat interpolation support: %s\n", (fFlatInterpolationSupport ? "YES" : "NO"));
r.appendf("No perspective interpolation support: %s\n", (fNoPerspectiveInterpolationSupport ?
"YES" : "NO"));
bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
+ bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
+
// 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.
// Used for specific driver bug work arounds
bool fCanUseMinAndAbsTogether : 1;
bool fMustForceNegatedAtanParamToFloat : 1;
+ bool fRequiresLocalOutputColorForFBFetch : 1;
const char* fVersionDeclString;
#include "glsl/GrGLSLUniformHandler.h"
#include "glsl/GrGLSLVarying.h"
-const char* GrGLSLFragmentShaderBuilder::kDstTextureColorName = "_dstColor";
+const char* GrGLSLFragmentShaderBuilder::kDstColorName = "_dstColor";
static const char* sample_offset_array_name(GrGLSLFPFragmentBuilder::Coordinates coords) {
static const char* kArrayNames[] = {
this->enableCustomOutput();
fOutputs[fCustomColorOutputIndex].setTypeModifier(GrShaderVar::kInOut_TypeModifier);
fbFetchColorName = DeclaredColorOutputName();
+ // Set the dstColor to an intermediate variable so we don't override it with the output
+ this->codeAppendf("vec4 %s = %s;", kDstColorName, fbFetchColorName);
}
- return fbFetchColorName;
- } else {
- return kDstTextureColorName;
}
+ return kDstColorName;
}
void GrGLSLFragmentShaderBuilder::enableAdvancedBlendEquationIfNeeded(GrBlendEquation equation) {
void onFinalize() override;
void defineSampleOffsetArray(const char* name, const SkMatrix&);
- static const char* kDstTextureColorName;
+ static const char* kDstColorName;
/*
* State that tracks which child proc in the proc tree is currently emitting code. This is
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
const char* dstColor = fragBuilder->dstColor();
+ bool needsLocalOutColor = false;
+
if (args.fXP.getDstTexture()) {
bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin();
fragBuilder->codeAppendf("vec4 %s = ", dstColor);
fragBuilder->appendTextureLookup(args.fTexSamplers[0], "_dstTexCoord", kVec2f_GrSLType);
fragBuilder->codeAppend(";");
+ } else {
+ needsLocalOutColor = args.fGLSLCaps->requiresLocalOutputColorForFBFetch();
+ }
+
+ const char* outColor = "_localColorOut";
+ if (!needsLocalOutColor) {
+ outColor = args.fOutputPrimary;
+ } else {
+ fragBuilder->codeAppendf("vec4 %s;", outColor);
}
this->emitBlendCodeForDstRead(fragBuilder,
args.fInputColor,
args.fInputCoverage,
dstColor,
- args.fOutputPrimary,
+ outColor,
args.fOutputSecondary,
args.fXP);
+ if (needsLocalOutColor) {
+ fragBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, outColor);
+ }
}
void GrGLSLXferProcessor::setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp) {