diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 7 | ||||
-rwxr-xr-x | src/gpu/glsl/GrGLSLCaps.cpp | 3 | ||||
-rwxr-xr-x | src/gpu/glsl/GrGLSLCaps.h | 3 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp | 8 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLFragmentShaderBuilder.h | 2 | ||||
-rw-r--r-- | src/gpu/glsl/GrGLSLXferProcessor.cpp | 16 |
6 files changed, 33 insertions, 6 deletions
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 75ae776879..3385dbce31 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -792,6 +792,13 @@ void GrGLCaps::initGLSL(const GrGLContextInfo& ctxInfo) { 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) { diff --git a/src/gpu/glsl/GrGLSLCaps.cpp b/src/gpu/glsl/GrGLSLCaps.cpp index 1f4b855f5d..b33e3082ec 100755 --- a/src/gpu/glsl/GrGLSLCaps.cpp +++ b/src/gpu/glsl/GrGLSLCaps.cpp @@ -23,6 +23,7 @@ GrGLSLCaps::GrGLSLCaps(const GrContextOptions& options) { fCanUseAnyFunctionInShader = true; fCanUseMinAndAbsTogether = true; fMustForceNegatedAtanParamToFloat = false; + fRequiresLocalOutputColorForFBFetch = false; fFlatInterpolationSupport = false; fNoPerspectiveInterpolationSupport = false; fMultisampleInterpolationSupport = false; @@ -73,6 +74,8 @@ SkString GrGLSLCaps::dump() const { 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")); diff --git a/src/gpu/glsl/GrGLSLCaps.h b/src/gpu/glsl/GrGLSLCaps.h index 19a34620dc..d8145e729d 100755 --- a/src/gpu/glsl/GrGLSLCaps.h +++ b/src/gpu/glsl/GrGLSLCaps.h @@ -91,6 +91,8 @@ public: 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. @@ -199,6 +201,7 @@ private: // Used for specific driver bug work arounds bool fCanUseMinAndAbsTogether : 1; bool fMustForceNegatedAtanParamToFloat : 1; + bool fRequiresLocalOutputColorForFBFetch : 1; const char* fVersionDeclString; diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp index e6ecf8c171..4513a69fc8 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp @@ -15,7 +15,7 @@ #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[] = { @@ -264,11 +264,11 @@ const char* GrGLSLFragmentShaderBuilder::dstColor() { 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) { diff --git a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h index 6845376261..55ef9db207 100644 --- a/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h +++ b/src/gpu/glsl/GrGLSLFragmentShaderBuilder.h @@ -212,7 +212,7 @@ private: 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 diff --git a/src/gpu/glsl/GrGLSLXferProcessor.cpp b/src/gpu/glsl/GrGLSLXferProcessor.cpp index f0f5efd37b..0f7a3db718 100644 --- a/src/gpu/glsl/GrGLSLXferProcessor.cpp +++ b/src/gpu/glsl/GrGLSLXferProcessor.cpp @@ -22,6 +22,8 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) { GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; const char* dstColor = fragBuilder->dstColor(); + bool needsLocalOutColor = false; + if (args.fXP.getDstTexture()) { bool topDown = kTopLeft_GrSurfaceOrigin == args.fXP.getDstTexture()->origin(); @@ -59,6 +61,15 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) { 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, @@ -66,9 +77,12 @@ void GrGLSLXferProcessor::emitCode(const EmitArgs& args) { 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) { |