diff options
-rw-r--r-- | src/gpu/effects/GrEdgeEffect.cpp | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 2 | ||||
-rw-r--r-- | src/gpu/gl/GrGLSL.cpp | 10 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 54 | ||||
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.h | 30 |
5 files changed, 82 insertions, 24 deletions
diff --git a/src/gpu/effects/GrEdgeEffect.cpp b/src/gpu/effects/GrEdgeEffect.cpp index dd7474fd00..6f56413963 100644 --- a/src/gpu/effects/GrEdgeEffect.cpp +++ b/src/gpu/effects/GrEdgeEffect.cpp @@ -38,7 +38,7 @@ public: builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); break; case GrEdgeEffect::kQuad_EdgeType: - GrAssert(builder->ctxInfo().caps()->shaderDerivativeSupport()); + SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName); // keep the derivative instructions outside the conditional @@ -56,12 +56,9 @@ public: fsName); builder->fsCodeAppendf("\t\t\tedgeAlpha = " "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n"); - if (kES2_GrGLBinding == builder->ctxInfo().binding()) { - builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n"); - } break; case GrEdgeEffect::kHairQuad_EdgeType: - GrAssert(builder->ctxInfo().caps()->shaderDerivativeSupport()); + SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName); builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); @@ -73,9 +70,6 @@ public: fsName); builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n"); builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); - if (kES2_GrGLBinding == builder->ctxInfo().binding()) { - builder->fHeader.append("#extension GL_OES_standard_derivatives: enable\n"); - } break; }; diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index ed3a87c1b7..cbaa765440 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -462,8 +462,6 @@ bool GrGLProgram::genProgram(const GrEffectStage* stages[]) { // the dual source output has no canonical var name, have to // declare an output, which is incompatible with gl_FragColor/gl_FragData. bool dualSourceOutputWritten = false; - builder.fHeader.append(GrGetGLSLVersionDecl(fContext.info().binding(), - fContext.info().glslGeneration())); GrGLShaderVar colorOutput; bool isColorDeclared = GrGLSLSetupFSColorOuput(fContext.info().glslGeneration(), diff --git a/src/gpu/gl/GrGLSL.cpp b/src/gpu/gl/GrGLSL.cpp index 64b6c11ada..570e61e53a 100644 --- a/src/gpu/gl/GrGLSL.cpp +++ b/src/gpu/gl/GrGLSL.cpp @@ -9,8 +9,7 @@ #include "GrGLShaderVar.h" #include "SkString.h" -GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, - const GrGLInterface* gl) { +GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, const GrGLInterface* gl) { GrGLSLVersion ver = GrGLGetGLSLVersion(gl); switch (binding) { case kDesktop_GrGLBinding: @@ -34,8 +33,7 @@ GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, } } -const char* GrGetGLSLVersionDecl(GrGLBinding binding, - GrGLSLGeneration gen) { +const char* GrGetGLSLVersionDecl(GrGLBinding binding, GrGLSLGeneration gen) { switch (gen) { case k110_GrGLSLGeneration: if (kES2_GrGLBinding == binding) { @@ -61,9 +59,7 @@ const char* GrGetGLSLVersionDecl(GrGLBinding binding, } } -bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen, - const char* nameIfDeclared, - GrGLShaderVar* var) { +bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen, const char* nameIfDeclared, GrGLShaderVar* var) { bool declaredOutput = k110_GrGLSLGeneration != gen; var->set(kVec4f_GrSLType, GrGLShaderVar::kOut_TypeModifier, diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp index e777b318b3..86cead41c3 100644 --- a/src/gpu/gl/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/GrGLShaderBuilder.cpp @@ -104,6 +104,7 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, , fCtxInfo(ctxInfo) , fUniformManager(uniformManager) , fCurrentStageIdx(kNonStageIdx) + , fFSFeaturesAddedMask(0) #if GR_GL_EXPERIMENTAL_GS , fUsesGS(desc.fExperimentalGS) #else @@ -157,6 +158,47 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, } } +bool GrGLShaderBuilder::enableFeature(GLSLFeature feature) { + switch (feature) { + case kStandardDerivatives_GLSLFeature: + if (!fCtxInfo.caps()->shaderDerivativeSupport()) { + return false; + } + if (kES2_GrGLBinding == fCtxInfo.binding()) { + this->addFSFeature(1 << kStandardDerivatives_GLSLFeature, + "GL_OES_standard_derivatives"); + } + return true; + default: + GrCrash("Unexpected GLSLFeature requested."); + return false; + } +} + +bool GrGLShaderBuilder::enablePrivateFeature(GLSLPrivateFeature feature) { + switch (feature) { + case kFragCoordConventions_GLSLPrivateFeature: + if (!fCtxInfo.caps()->fragCoordConventionsSupport()) { + return false; + } + if (fCtxInfo.glslGeneration() < k150_GrGLSLGeneration) { + this->addFSFeature(1 << kFragCoordConventions_GLSLPrivateFeature, + "GL_ARB_fragment_coord_conventions"); + } + return true; + default: + GrCrash("Unexpected GLSLPrivateFeature requested."); + return false; + } +} + +void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionName) { + if (!(featureBit & fFSFeaturesAddedMask)) { + fFSHeader.appendf("#extension %s: require\n", extensionName); + fFSFeaturesAddedMask |= featureBit; + } +} + const char* GrGLShaderBuilder::dstColor() const { if (fDstCopySampler.isInitialized()) { return kDstColorName; @@ -388,9 +430,7 @@ const char* GrGLShaderBuilder::fragmentPosition() { #if 1 if (fCtxInfo.caps()->fragCoordConventionsSupport()) { if (!fSetupFragPosition) { - if (fCtxInfo.glslGeneration() < k150_GrGLSLGeneration) { - fFSHeader.append("#extension GL_ARB_fragment_coord_conventions: require\n"); - } + SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature)); fFSInputs.push_back().set(kVec4f_GrSLType, GrGLShaderVar::kIn_TypeModifier, "gl_FragCoord", @@ -507,9 +547,11 @@ void GrGLShaderBuilder::appendUniformDecls(ShaderType stype, SkString* out) cons } void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { + const char* version = GrGetGLSLVersionDecl(fCtxInfo.binding(), fCtxInfo.glslGeneration()); + switch (type) { case kVertex_ShaderType: - *shaderStr = fHeader; + *shaderStr = version; this->appendUniformDecls(kVertex_ShaderType, shaderStr); this->appendDecls(fVSAttrs, shaderStr); this->appendDecls(fVSOutputs, shaderStr); @@ -519,7 +561,7 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { break; case kGeometry_ShaderType: if (fUsesGS) { - *shaderStr = fHeader; + *shaderStr = version; shaderStr->append(fGSHeader); this->appendDecls(fGSInputs, shaderStr); this->appendDecls(fGSOutputs, shaderStr); @@ -531,7 +573,7 @@ void GrGLShaderBuilder::getShader(ShaderType type, SkString* shaderStr) const { } break; case kFragment_ShaderType: - *shaderStr = fHeader; + *shaderStr = version; append_default_precision_qualifier(kDefaultFragmentPrecision, fCtxInfo.binding(), shaderStr); diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h index 4e39f91e35..8406793671 100644 --- a/src/gpu/gl/GrGLShaderBuilder.h +++ b/src/gpu/gl/GrGLShaderBuilder.h @@ -107,6 +107,22 @@ public: GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLProgramDesc&); /** + * Use of these features may require a GLSL extension to be enabled. Shaders may not compile + * if code is added that uses one of these features without calling enableFeature() + */ + enum GLSLFeature { + kStandardDerivatives_GLSLFeature = 0, + + kLastGLSLFeature = kStandardDerivatives_GLSLFeature + }; + + /** + * If the feature is supported then true is returned and any necessary #extension declarations + * are added to the shaders. If the feature is not supported then false will be returned. + */ + bool enableFeature(GLSLFeature); + + /** * Called by GrGLEffects to add code to one of the shaders. */ void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { @@ -313,7 +329,6 @@ private: // TODO: Everything below here private. public: - SkString fHeader; // VS+FS, GLSL version, etc VarArray fVSAttrs; VarArray fVSOutputs; VarArray fGSInputs; @@ -327,6 +342,18 @@ private: kNonStageIdx = -1, }; + /** + * Features that should only be enabled by GrGLShaderBuilder itself. + */ + enum GLSLPrivateFeature { + kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1 + }; + bool enablePrivateFeature(GLSLPrivateFeature); + + // If we ever have VS/GS features we can expand this to take a bitmask of ShaderType and track + // the enables separately for each shader. + void addFSFeature(uint32_t featureBit, const char* extensionName); + // Interpretation of DstReadKey when generating code enum { kNoDstRead_DstReadKey = 0, @@ -338,6 +365,7 @@ private: const GrGLContextInfo& fCtxInfo; GrGLUniformManager& fUniformManager; int fCurrentStageIdx; + uint32_t fFSFeaturesAddedMask; SkString fFSFunctions; SkString fFSHeader; |