diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-02-10 15:56:06 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-02-10 15:56:06 +0000 |
commit | e55fd0f188a2b0b137ddfd9728da58481e2309ef (patch) | |
tree | b3dc09e6ad3fe234e9a7d1d9e40f73b705f98118 /src | |
parent | 368b4192001ccb3c14fd54f96fffe52fde545cb9 (diff) |
Pull GLSL helpers out of GrGLProgram.cpp
Review URL: http://codereview.appspot.com/5652047/
git-svn-id: http://skia.googlecode.com/svn/trunk@3161 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrGLProgram.cpp | 100 | ||||
-rw-r--r-- | src/gpu/GrGLSL.cpp | 62 | ||||
-rw-r--r-- | src/gpu/GrGLSL.h | 54 | ||||
-rw-r--r-- | src/gpu/GrGLShaderVar.h | 6 | ||||
-rw-r--r-- | src/gpu/GrGpuGLShaders.cpp | 6 |
5 files changed, 131 insertions, 97 deletions
diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp index 610446d615..e77638f098 100644 --- a/src/gpu/GrGLProgram.cpp +++ b/src/gpu/GrGLProgram.cpp @@ -22,23 +22,6 @@ enum { kUseUniform = 2000 }; - -const char* GrPrecision(const GrGLInterface* gl) { - if (gl->supportsES2()) { - return "mediump"; - } else { - return " "; - } -} - -const char* GrShaderPrecision(const GrGLInterface* gl) { - if (gl->supportsES2()) { - return "precision mediump float;\n"; - } else { - return ""; - } -} - } // namespace #define PRINT_SHADERS 0 @@ -380,29 +363,6 @@ static void addColorMatrix(GrStringBuilder* fsCode, const char * outputVar, namespace { -const char* glsl_version_string(const GrGLInterface* gl, - GrGLSLGeneration v) { - switch (v) { - case k110_GLSLGeneration: - if (gl->supportsES2()) { - // ES2s shader language is based on version 1.20 but is version - // 1.00 of the ES language. - return "#version 100\n"; - } else { - return "#version 110\n"; - } - case k130_GLSLGeneration: - GrAssert(!gl->supportsES2()); - return "#version 130\n"; - case k150_GLSLGeneration: - GrAssert(!gl->supportsES2()); - return "#version 150\n"; - default: - GrCrash("Unknown GL version."); - return ""; // suppress warning - } -} - // Adds a var that is computed in the VS and read in FS. // If there is a GS it will just pass it through. void append_varying(GrGLShaderVar::Type type, @@ -568,29 +528,6 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl, namespace { -// returns true if the color output was explicitly declared or not. -bool decl_and_get_fs_color_output(GrGLSLGeneration v, - VarArray* fsOutputs, - const char** name) { - switch (v) { - case k110_GLSLGeneration: - *name = "gl_FragColor"; - return false; - break; - case k130_GLSLGeneration: // fallthru - case k150_GLSLGeneration: - *name = declared_color_output_name(); - fsOutputs->push_back().set(GrGLShaderVar::kVec4f_Type, - GrGLShaderVar::kOut_TypeModifier, - declared_color_output_name()); - return true; - break; - default: - GrCrash("Unknown GLSL version."); - return false; // suppress warning - } -} - void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput, GrGLProgram::CachedData* programData, ShaderCodeSegments* segments, @@ -664,7 +601,7 @@ void GrGLProgram::genGeometryShader(const GrGLInterface* gl, ShaderCodeSegments* segments) const { #if GR_GL_EXPERIMENTAL_GS if (fProgramDesc.fExperimentalGS) { - GrAssert(glslGeneration >= k150_GLSLGeneration); + GrAssert(glslGeneration >= k150_GrGLSLGeneration); segments->fGSHeader.append("layout(triangles) in;\n" "layout(triangle_strip, max_vertices = 6) out;\n"); segments->fGSCode.append("void main() {\n" @@ -758,12 +695,17 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, // the dual source output has no canonical var name, have to // declare an output, which is incompatible with gl_FragColor/gl_FragData. - const char* fsColorOutput = NULL; bool dualSourceOutputWritten = false; - segments.fHeader.printf(glsl_version_string(gl, glslGeneration)); - bool isColorDeclared = decl_and_get_fs_color_output(glslGeneration, - &segments.fFSOutputs, - &fsColorOutput); + segments.fHeader.printf(GrGetGLSLVersionDecl(gl->fBindingsExported, + glslGeneration)); + + GrGLShaderVar colorOutput; + bool isColorDeclared = GrGLSLSetupFSColorOuput(glslGeneration, + declared_color_output_name(), + &colorOutput); + if (isColorDeclared) { + segments.fFSOutputs.push_back(colorOutput); + } #if GR_GL_ATTRIBUTE_MATRICES segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type, @@ -872,7 +814,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, SkXfermode::kZero_Coeff == colorCoeff && !applyColorMatrix) { segments.fFSCode.appendf("\t%s = %s;\n", - fsColorOutput, + colorOutput.getName().c_str(), all_zeros_vec(4)); wroteFragColorZero = true; } else if (SkXfermode::kDst_Mode != fProgramDesc.fColorFilterXfermode) { @@ -1005,21 +947,21 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl, if (!wroteFragColorZero) { if (coverageIsZero) { segments.fFSCode.appendf("\t%s = %s;\n", - fsColorOutput, + colorOutput.getName().c_str(), all_zeros_vec(4)); } else { - modulate_helper(fsColorOutput, + modulate_helper(colorOutput.getName().c_str(), inColor.c_str(), inCoverage.c_str(), &segments.fFSCode); } if (ProgramDesc::kNo_OutputPM == fProgramDesc.fOutputPM) { segments.fFSCode.appendf("\t%s = %s.a <= 0.0 ? vec4(0,0,0,0) : vec4(%s.rgb / %s.a, %s.a);\n", - fsColorOutput, - fsColorOutput, - fsColorOutput, - fsColorOutput, - fsColorOutput); + colorOutput.getName().c_str(), + colorOutput.getName().c_str(), + colorOutput.getName().c_str(), + colorOutput.getName().c_str(), + colorOutput.getName().c_str()); } } @@ -1169,13 +1111,13 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl, temps.reset(); append_string(segments.fHeader, &strs, &lengths); - GrStringBuilder precisionStr(GrShaderPrecision(gl)); + GrStringBuilder precisionStr(GrGetGLSLShaderPrecisionDecl(gl->fBindingsExported)); append_string(precisionStr, &strs, &lengths); append_decls(segments.fFSUnis, gl, &strs, &lengths, &temps, glslGeneration); append_decls(segments.fFSInputs, gl, &strs, &lengths, &temps, glslGeneration); // We shouldn't have declared outputs on 1.10 - GrAssert(k110_GLSLGeneration != glslGeneration || + GrAssert(k110_GrGLSLGeneration != glslGeneration || segments.fFSOutputs.empty()); append_decls(segments.fFSOutputs, gl, &strs, &lengths, &temps, glslGeneration); diff --git a/src/gpu/GrGLSL.cpp b/src/gpu/GrGLSL.cpp index 1062c81a86..e933ee87c9 100644 --- a/src/gpu/GrGLSL.cpp +++ b/src/gpu/GrGLSL.cpp @@ -6,27 +6,77 @@ */ #include "GrGLSL.h" +#include "GrGLShaderVar.h" -GrGLSLGeneration GetGLSLGeneration(GrGLBinding binding, +GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, const GrGLInterface* gl) { GrGLSLVersion ver = GrGLGetGLSLVersion(gl); switch (binding) { case kDesktop_GrGLBinding: GrAssert(ver >= GR_GLSL_VER(1,10)); if (ver >= GR_GLSL_VER(1,50)) { - return k150_GLSLGeneration; + return k150_GrGLSLGeneration; } else if (ver >= GR_GLSL_VER(1,30)) { - return k130_GLSLGeneration; + return k130_GrGLSLGeneration; } else { - return k110_GLSLGeneration; + return k110_GrGLSLGeneration; } case kES2_GrGLBinding: // version 1.00 of ES GLSL based on ver 1.20 of desktop GLSL GrAssert(ver >= GR_GL_VER(1,00)); - return k110_GLSLGeneration; + return k110_GrGLSLGeneration; default: GrCrash("Unknown GL Binding"); - return k110_GLSLGeneration; // suppress warning + return k110_GrGLSLGeneration; // suppress warning } } +const char* GrGetGLSLVersionDecl(GrGLBinding binding, + GrGLSLGeneration gen) { + switch (gen) { + case k110_GrGLSLGeneration: + if (kES2_GrGLBinding == binding) { + // ES2s shader language is based on version 1.20 but is version + // 1.00 of the ES language. + return "#version 100\n"; + } else { + GrAssert(kDesktop_GrGLBinding == binding); + return "#version 110\n"; + } + case k130_GrGLSLGeneration: + GrAssert(kDesktop_GrGLBinding == binding); + return "#version 130\n"; + case k150_GrGLSLGeneration: + GrAssert(kDesktop_GrGLBinding == binding); + return "#version 150\n"; + default: + GrCrash("Unknown GL version."); + return ""; // suppress warning + } +} + +const char* GrGetGLSLVarPrecisionDeclType(GrGLBinding binding) { + if (kES2_GrGLBinding == binding) { + return "mediump"; + } else { + return " "; + } +} + +const char* GrGetGLSLShaderPrecisionDecl(GrGLBinding binding) { + if (kES2_GrGLBinding == binding) { + return "precision mediump float;\n"; + } else { + return ""; + } +} + +bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen, + const char* nameIfDeclared, + GrGLShaderVar* var) { + bool declaredOutput = k110_GrGLSLGeneration != gen; + var->set(GrGLShaderVar::kVec4f_Type, + GrGLShaderVar::kOut_TypeModifier, + declaredOutput ? nameIfDeclared : "gl_FragColor"); + return declaredOutput; +} diff --git a/src/gpu/GrGLSL.h b/src/gpu/GrGLSL.h index 501d1bab7a..5b9c5b631f 100644 --- a/src/gpu/GrGLSL.h +++ b/src/gpu/GrGLSL.h @@ -10,25 +10,67 @@ #include "GrGLInterface.h" +class GrGLShaderVar; + // Limited set of GLSL versions we build shaders for. Caller should round // down the GLSL version to one of these enums. enum GrGLSLGeneration { /** * Desktop GLSL 1.10 and ES2 shading lang (based on desktop GLSL 1.20) */ - k110_GLSLGeneration, + k110_GrGLSLGeneration, /** * Desktop GLSL 1.30 */ - k130_GLSLGeneration, + k130_GrGLSLGeneration, /** * Dekstop GLSL 1.50 */ - k150_GLSLGeneration, + k150_GrGLSLGeneration, }; -GrGLSLGeneration GetGLSLGeneration(GrGLBinding binding, - const GrGLInterface* gl); +/** + * Gets the most recent GLSL Generation compatible with the OpenGL context. + */ +GrGLSLGeneration GrGetGLSLGeneration(GrGLBinding binding, + const GrGLInterface* gl); -#endif +/** + * Returns a string to include at the begining of a shader to declare the GLSL + * version. + */ +const char* GrGetGLSLVersionDecl(GrGLBinding binding, + GrGLSLGeneration v); + +/** + * Returns a string to include in a variable decleration to set the fp precision + * or an emptry string if precision is not required. + */ +const char* GrGetGLSLVarPrecisionDeclType(GrGLBinding binding); +/** + * Returns a string to set the default fp precision for an entire shader, or + * an emptry string if precision is not required. + */ +const char* GrGetGLSLShaderPrecisionDecl(GrGLBinding binding); + +/** + * Depending on the GLSL version being emitted there may be an assumed output + * variable from the fragment shader for the color. Otherwise, the shader must + * declare an output variable for the color. If this function returns true: + * * Parameter var's name will be set to nameIfDeclared + * * The variable must be declared in the fragment shader + * * The variable has to be bound as the color output + * (using glBindFragDataLocation) + * If the function returns false: + * * Parameter var's name will be set to the GLSL built-in color output name. + * * Do not declare the variable in the shader. + * * Do not use glBindFragDataLocation to bind the variable + * In either case var is initialized to represent the color output in the + * shader. + */ + bool GrGLSLSetupFSColorOuput(GrGLSLGeneration gen, + const char* nameIfDeclared, + GrGLShaderVar* var); + +#endif diff --git a/src/gpu/GrGLShaderVar.h b/src/gpu/GrGLShaderVar.h index 1d5d7cad5d..7bec9f95e5 100644 --- a/src/gpu/GrGLShaderVar.h +++ b/src/gpu/GrGLShaderVar.h @@ -278,13 +278,13 @@ private: case kNone_TypeModifier: return ""; case kOut_TypeModifier: - return k110_GLSLGeneration == gen ? "varying" : "out"; + return k110_GrGLSLGeneration == gen ? "varying" : "out"; case kIn_TypeModifier: - return k110_GLSLGeneration == gen ? "varying" : "in"; + return k110_GrGLSLGeneration == gen ? "varying" : "in"; case kUniform_TypeModifier: return "uniform"; case kAttribute_TypeModifier: - return k110_GLSLGeneration == gen ? "attribute" : "in"; + return k110_GrGLSLGeneration == gen ? "attribute" : "in"; default: GrCrash("Unknown shader variable type modifier."); return ""; // suppress warning diff --git a/src/gpu/GrGpuGLShaders.cpp b/src/gpu/GrGpuGLShaders.cpp index b8e0999ab8..d03c9f224e 100644 --- a/src/gpu/GrGpuGLShaders.cpp +++ b/src/gpu/GrGpuGLShaders.cpp @@ -166,7 +166,7 @@ bool random_bool(GrRandom* r) { bool GrGpuGLShaders::programUnitTest() { GrGLSLGeneration glslGeneration = - GetGLSLGeneration(this->glBinding(), this->glInterface()); + GrGetGLSLGeneration(this->glBinding(), this->glInterface()); static const int STAGE_OPTS[] = { 0, StageDesc::kNoPerspective_OptFlagBit, @@ -306,7 +306,7 @@ GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl) : GrGpuGL(gl, get_binding_in_use(gl)) { GrGLSLGeneration glslGeneration = - GetGLSLGeneration(this->glBinding(), gl); + GrGetGLSLGeneration(this->glBinding(), gl); // Enable supported shader-related caps if (kDesktop_GrGLBinding == this->glBinding()) { @@ -317,7 +317,7 @@ GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl) // we don't support GL_ARB_geometry_shader4, just GL 3.2+ GS fCaps.fGeometryShaderSupport = this->glVersion() >= GR_GL_VER(3,2) && - glslGeneration >= k150_GLSLGeneration; + glslGeneration >= k150_GrGLSLGeneration; } else { fCaps.fShaderDerivativeSupport = this->hasExtension("GL_OES_standard_derivatives"); |