Make GrGLShaderVar objects aware of whether they are uniform, varying, or
authortomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 8 Dec 2011 14:44:10 +0000 (14:44 +0000)
committertomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Thu, 8 Dec 2011 14:44:10 +0000 (14:44 +0000)
attribute varibles. Extract GLSL generation enum and utility function into
new GrGLSL header.

git-svn-id: http://skia.googlecode.com/svn/trunk@2827 2bbb7eff-a529-9590-31e7-b0007b416f81

gyp/gpu.gyp
src/gpu/GrGLProgram.cpp
src/gpu/GrGLProgram.h
src/gpu/GrGLSL.cpp [new file with mode: 0644]
src/gpu/GrGLSL.h [new file with mode: 0644]
src/gpu/GrGLShaderVar.h
src/gpu/GrGpuGLShaders.cpp

index f0173f7..9fcded1 100644 (file)
         '../src/gpu/GrGLRenderTarget.cpp',
         '../src/gpu/GrGLRenderTarget.h',
         '../src/gpu/GrGLShaderVar.h',
+        '../src/gpu/GrGLSL.cpp',
+        '../src/gpu/GrGLSL.h',
         '../src/gpu/GrGLStencilBuffer.cpp',
         '../src/gpu/GrGLStencilBuffer.h',
         '../src/gpu/GrGLTexture.cpp',
index 9395c0e..b7e902d 100644 (file)
@@ -369,9 +369,9 @@ static void addColorFilter(GrStringBuilder* fsCode, const char * outputVar,
 namespace {
 
 const char* glsl_version_string(const GrGLInterface* gl,
-                                GrGLProgram::GLSLVersion v) {
+                                GrGLSLGeneration v) {
     switch (v) {
-        case GrGLProgram::k110_GLSLVersion:
+        case k110_GLSLGeneration:
             if (gl->supportsES2()) {
                 // ES2s shader language is based on version 1.20 but is version
                 // 1.00 of the ES language.
@@ -379,10 +379,10 @@ const char* glsl_version_string(const GrGLInterface* gl,
             } else {
                 return "#version 110\n";
             }
-        case GrGLProgram::k130_GLSLVersion:
+        case k130_GLSLGeneration:
             GrAssert(!gl->supportsES2());
             return "#version 130\n";
-        case GrGLProgram::k150_GLSLVersion:
+        case k150_GLSLGeneration:
             GrAssert(!gl->supportsES2());
             return "#version 150\n";
         default:
@@ -400,6 +400,8 @@ void append_varying(GrGLShaderVar::Type type,
                     const char** fsInName = NULL) {
     segments->fVSOutputs.push_back();
     segments->fVSOutputs.back().setType(type);
+    segments->fVSOutputs.back().setTypeModifier(
+        GrGLShaderVar::kOut_TypeModifier);
     segments->fVSOutputs.back().accessName()->printf("v%s", name);
     if (vsOutName) {
         *vsOutName = segments->fVSOutputs.back().getName().c_str();
@@ -411,11 +413,15 @@ void append_varying(GrGLShaderVar::Type type,
         // and output as non-array.
         segments->fGSInputs.push_back();
         segments->fGSInputs.back().setType(type);
+        segments->fGSInputs.back().setTypeModifier(
+            GrGLShaderVar::kIn_TypeModifier);
         segments->fGSInputs.back().setUnsizedArray();
         *segments->fGSInputs.back().accessName() =
             segments->fVSOutputs.back().getName();
         segments->fGSOutputs.push_back();
         segments->fGSOutputs.back().setType(type);
+        segments->fGSOutputs.back().setTypeModifier(
+            GrGLShaderVar::kOut_TypeModifier);
         segments->fGSOutputs.back().accessName()->printf("g%s", name);
         fsName = segments->fGSOutputs.back().accessName();
     } else {
@@ -423,6 +429,8 @@ void append_varying(GrGLShaderVar::Type type,
     }
     segments->fFSInputs.push_back();
     segments->fFSInputs.back().setType(type);
+    segments->fFSInputs.back().setTypeModifier(
+        GrGLShaderVar::kIn_TypeModifier);
     segments->fFSInputs.back().setName(*fsName);
     if (fsInName) {
         *fsInName = fsName->c_str();
@@ -450,6 +458,7 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
                                   ShaderCodeSegments* segments) const {
     if (fProgramDesc.fEdgeAANumEdges > 0) {
         segments->fFSUnis.push_back().set(GrGLShaderVar::kVec3f_Type,
+                                          GrGLShaderVar::kUniform_TypeModifier,
                                           EDGES_UNI_NAME,
                                           fProgramDesc.fEdgeAANumEdges);
         programData->fUniLocations.fEdgesUni = kUseUniform;
@@ -499,8 +508,10 @@ void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
         *coverageVar = "edgeAlpha";
     } else  if (layout & GrDrawTarget::kEdge_VertexLayoutBit) {
         const char *vsName, *fsName;
-        append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments, &vsName, &fsName);
-        segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, EDGE_ATTR_NAME);
+        append_varying(GrGLShaderVar::kVec4f_Type, "Edge", segments,
+            &vsName, &fsName);
+        segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
+            GrGLShaderVar::kAttribute_TypeModifier, EDGE_ATTR_NAME);
         segments->fVSCode.appendf("\t%s = " EDGE_ATTR_NAME ";\n", vsName);
         if (GrDrawState::kHairLine_EdgeType == fProgramDesc.fVertexEdgeType) {
             segments->fFSCode.appendf("\tfloat edgeAlpha = abs(dot(vec3(gl_FragCoord.xy,1), %s.xyz));\n", fsName);
@@ -528,18 +539,19 @@ 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(GrGLProgram::GLSLVersion v,
+bool decl_and_get_fs_color_output(GrGLSLGeneration v,
                                   VarArray* fsOutputs,
                                   const char** name) {
     switch (v) {
-        case GrGLProgram::k110_GLSLVersion:
+        case k110_GLSLGeneration:
             *name = "gl_FragColor";
             return false;
             break;
-        case GrGLProgram::k130_GLSLVersion: // fallthru
-        case GrGLProgram::k150_GLSLVersion:
+        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;
@@ -556,7 +568,8 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
     switch (colorInput) {
         case GrGLProgram::ProgramDesc::kAttribute_ColorInput: {
             segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
-                                               COL_ATTR_NAME);
+                GrGLShaderVar::kAttribute_TypeModifier,
+                COL_ATTR_NAME);
             const char *vsName, *fsName;
             append_varying(GrGLShaderVar::kVec4f_Type, "Color", segments, &vsName, &fsName);
             segments->fVSCode.appendf("\t%s = " COL_ATTR_NAME ";\n", vsName);
@@ -564,7 +577,8 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
             } break;
         case GrGLProgram::ProgramDesc::kUniform_ColorInput:
             segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
-                                              COL_UNI_NAME);
+                GrGLShaderVar::kUniform_TypeModifier,
+                COL_UNI_NAME);
             programData->fUniLocations.fColorUni = kUseUniform;
             *inColor = COL_UNI_NAME;
             break;
@@ -582,6 +596,7 @@ void genInputColor(GrGLProgram::ProgramDesc::ColorInput colorInput,
 void genPerVertexCoverage(ShaderCodeSegments* segments,
                           GrStringBuilder* inCoverage) {
     segments->fVSAttrs.push_back().set(GrGLShaderVar::kFloat_Type,
+                                       GrGLShaderVar::kAttribute_TypeModifier,
                                        COV_ATTR_NAME);
     const char *vsName, *fsName;
     append_varying(GrGLShaderVar::kFloat_Type, "Coverage", 
@@ -599,11 +614,11 @@ void genPerVertexCoverage(ShaderCodeSegments* segments,
 }
 
 void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
-                                    GLSLVersion glslVersion,
+                                    GrGLSLGeneration glslGeneration,
                                     ShaderCodeSegments* segments) const {
 #if GR_GL_EXPERIMENTAL_GS
     if (fProgramDesc.fExperimentalGS) {
-        GrAssert(glslVersion >= k150_GLSLVersion);
+        GrAssert(glslGeneration >= k150_GLSLGeneration);
         segments->fGSHeader.append("layout(triangles) in;\n"
                                    "layout(triangle_strip, max_vertices = 6) out;\n");
         segments->fGSCode.append("void main() {\n"
@@ -628,7 +643,7 @@ void GrGLProgram::genGeometryShader(const GrGLInterface* gl,
 }
 
 bool GrGLProgram::genProgram(const GrGLInterface* gl,
-                             GLSLVersion glslVersion,
+                             GrGLSLGeneration glslGeneration,
                              GrGLProgram::CachedData* programData) const {
 
     ShaderCodeSegments segments;
@@ -676,19 +691,22 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
     // 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, glslVersion));
-    bool isColorDeclared = decl_and_get_fs_color_output(glslVersion,
+    segments.fHeader.printf(glsl_version_string(gl, glslGeneration));
+    bool isColorDeclared = decl_and_get_fs_color_output(glslGeneration,
                                                         &segments.fFSOutputs,
                                                         &fsColorOutput);
 
 #if GR_GL_ATTRIBUTE_MATRICES
-    segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
+    segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type,
+        GrGLShaderVar::kAttribute_TypeModifier, VIEW_MATRIX_NAME);
     programData->fUniLocations.fViewMatrixUni = kSetAsAttribute;
 #else
-    segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
+    segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type,
+        GrGLShaderVar::kUniform_TypeModifier, VIEW_MATRIX_NAME);
     programData->fUniLocations.fViewMatrixUni = kUseUniform;
 #endif
-    segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type, POS_ATTR_NAME);
+    segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
+        GrGLShaderVar::kAttribute_TypeModifier, POS_ATTR_NAME);
 
     segments.fVSCode.append(
         "void main() {\n"
@@ -716,7 +734,8 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
         if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
             tex_attr_name(t, texCoordAttrs + t);
             segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
-                                              texCoordAttrs[t].c_str());
+                GrGLShaderVar::kAttribute_TypeModifier,
+                texCoordAttrs[t].c_str());
         }
     }
 
@@ -775,6 +794,7 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
     }
     if (needColorFilterUniform) {
         segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
+                                         GrGLShaderVar::kUniform_TypeModifier,
                                          COL_FILTER_UNI_NAME);
         programData->fUniLocations.fColorFilterUni = kUseUniform;
     }
@@ -854,7 +874,8 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
         }
         if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
             segments.fFSOutputs.push_back().set(GrGLShaderVar::kVec4f_Type,
-                                                dual_source_output_name());
+                GrGLShaderVar::kOut_TypeModifier,
+                dual_source_output_name());
             bool outputIsZero = false;
             GrStringBuilder coeff;
             if (ProgramDesc::kCoverage_DualSrcOutput !=
@@ -908,13 +929,13 @@ bool GrGLProgram::genProgram(const GrGLInterface* gl,
     ///////////////////////////////////////////////////////////////////////////
     // insert GS
 #if GR_DEBUG
-    this->genGeometryShader(gl, glslVersion, &segments);
+    this->genGeometryShader(gl, glslGeneration, &segments);
 #endif
 
     ///////////////////////////////////////////////////////////////////////////
     // compile and setup attribs and unis
 
-    if (!CompileShaders(gl, glslVersion, segments, programData)) {
+    if (!CompileShaders(gl, glslGeneration, segments, programData)) {
         return false;
     }
 
@@ -934,14 +955,11 @@ namespace {
 
 inline void expand_decls(const VarArray& vars,
                          const GrGLInterface* gl,
-                         const char* prefix,
-                         GrStringBuilder* string) {
+                         GrStringBuilder* string,
+                         GrGLSLGeneration gen) {
     const int count = vars.count();
     for (int i = 0; i < count; ++i) {
-        string->append(prefix);
-        string->append(" ");
-        vars[i].appendDecl(gl, string);
-        string->append(";\n");
+        vars[i].appendDecl(gl, string, gen);
     }
 }
 
@@ -980,18 +998,18 @@ inline void append_string(const GrStringBuilder& str,
 
 inline void append_decls(const VarArray& vars,
                          const GrGLInterface* gl,
-                         const char* prefix,
                          StrArray* strings,
                          LengthArray* lengths,
-                         TempArray* temp) {
-    expand_decls(vars, gl, prefix, &temp->push_back());
+                         TempArray* temp,
+                         GrGLSLGeneration gen) {
+    expand_decls(vars, gl, &temp->push_back(), gen);
     append_string(temp->back(), strings, lengths);
 }
 
 }
 
 bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
-                                 GLSLVersion glslVersion,
+                                 GrGLSLGeneration glslGeneration,
                                  const ShaderCodeSegments& segments,
                                  CachedData* programData) {
     enum { kPreAllocStringCnt = 8 };
@@ -1004,19 +1022,12 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
     GrStringBuilder inputs;
     GrStringBuilder outputs;
 
-    static const char* gVaryingPrefixes[2][2] = {{"varying", "varying"},
-                                                 {"out", "in"}};
-    const char** varyingPrefixes = k110_GLSLVersion == glslVersion ?
-                                                    gVaryingPrefixes[0] :
-                                                    gVaryingPrefixes[1];
-    const char* attributePrefix = k110_GLSLVersion == glslVersion ?
-                                                    "attribute" :
-                                                    "in";
-
     append_string(segments.fHeader, &strs, &lengths);
-    append_decls(segments.fVSUnis, gl, "uniform", &strs, &lengths, &temps);
-    append_decls(segments.fVSAttrs, gl, attributePrefix, &strs, &lengths, &temps);
-    append_decls(segments.fVSOutputs, gl, varyingPrefixes[0], &strs, &lengths, &temps);
+    append_decls(segments.fVSUnis, gl, &strs, &lengths, &temps, glslGeneration);
+    append_decls(segments.fVSAttrs, gl, &strs, &lengths,
+                 &temps, glslGeneration);
+    append_decls(segments.fVSOutputs, gl, &strs, &lengths,
+                 &temps, glslGeneration);
     append_string(segments.fVSCode, &strs, &lengths);
 
 #if PRINT_SHADERS
@@ -1037,8 +1048,10 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
         temps.reset();
         append_string(segments.fHeader, &strs, &lengths);
         append_string(segments.fGSHeader, &strs, &lengths);
-        append_decls(segments.fGSInputs, gl, "in", &strs, &lengths, &temps);
-        append_decls(segments.fGSOutputs, gl, "out", &strs, &lengths, &temps);
+        append_decls(segments.fGSInputs, gl, &strs, &lengths,
+                     &temps, glslGeneration);
+        append_decls(segments.fGSOutputs, gl, &strs, &lengths,
+                     &temps, glslGeneration);
         append_string(segments.fGSCode, &strs, &lengths);
 #if PRINT_SHADERS
         print_shader(strs.count(), &strs[0], &lengths[0]);
@@ -1058,11 +1071,14 @@ bool GrGLProgram::CompileShaders(const GrGLInterface* gl,
     append_string(segments.fHeader, &strs, &lengths);
     GrStringBuilder precisionStr(GrShaderPrecision(gl));
     append_string(precisionStr, &strs, &lengths);
-    append_decls(segments.fFSUnis, gl, "uniform", &strs, &lengths, &temps);
-    append_decls(segments.fFSInputs, gl, varyingPrefixes[1], &strs, &lengths, &temps);
+    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_GLSLVersion != glslVersion || segments.fFSOutputs.empty());
-    append_decls(segments.fFSOutputs, gl, "out", &strs, &lengths, &temps);
+    GrAssert(k110_GLSLGeneration != glslGeneration ||
+             segments.fFSOutputs.empty());
+    append_decls(segments.fFSOutputs, gl, &strs, &lengths,
+                 &temps, glslGeneration);
     append_string(segments.fFSFunctions, &strs, &lengths);
     append_string(segments.fFSCode, &strs, &lengths);
 
@@ -1334,6 +1350,7 @@ GrGLShaderVar* genRadialVS(int stageNum,
 
     GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
     radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
+    radial2FSParams->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
     radial2FSParams->setArrayCount(6);
     radial2_param_name(stageNum, radial2FSParams->accessName());
     segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
@@ -1523,9 +1540,11 @@ void genConvolutionVS(int stageNum,
     //GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
     *kernel = &segments->fFSUnis.push_back();
     (*kernel)->setType(GrGLShaderVar::kFloat_Type);
+    (*kernel)->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
     (*kernel)->setArrayCount(desc.fKernelWidth);
     GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
     imgInc->setType(GrGLShaderVar::kVec2f_Type);
+    imgInc->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
 
     convolve_param_names(stageNum,
                          (*kernel)->accessName(),
@@ -1612,9 +1631,11 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
         GrGLShaderVar* mat;
     #if GR_GL_ATTRIBUTE_MATRICES
         mat = &segments->fVSAttrs.push_back();
+        mat->setTypeModifier(GrGLShaderVar::kAttribute_TypeModifier);
         locations->fTextureMatrixUni = kSetAsAttribute;
     #else
         mat = &segments->fVSUnis.push_back();
+        mat->setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
         locations->fTextureMatrixUni = kUseUniform;
     #endif
         tex_matrix_name(stageNum, mat->accessName());
@@ -1628,14 +1649,16 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
         }
     }
 
-    segments->fFSUnis.push_back().setType(GrGLShaderVar::kSampler2D_Type);
+    segments->fFSUnis.push_back().set(GrGLShaderVar::kSampler2D_Type,
+        GrGLShaderVar::kUniform_TypeModifier, "");
     sampler_name(stageNum, segments->fFSUnis.back().accessName());
     locations->fSamplerUni = kUseUniform;
     const char* samplerName = segments->fFSUnis.back().getName().c_str();
 
     const char* texelSizeName = NULL;
     if (StageDesc::k2x2_FetchMode == desc.fFetchMode) {
-        segments->fFSUnis.push_back().setType(GrGLShaderVar::kVec2f_Type);
+        segments->fFSUnis.push_back().set(GrGLShaderVar::kVec2f_Type,
+            GrGLShaderVar::kUniform_TypeModifier, "");
         normalized_texel_size_name(stageNum, segments->fFSUnis.back().accessName());
         texelSizeName = segments->fFSUnis.back().getName().c_str();
     }
@@ -1758,7 +1781,8 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
         StageDesc::kCustomTextureDomain_OptFlagBit) {
         GrStringBuilder texDomainName;
         tex_domain_name(stageNum, &texDomainName);
-        segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, texDomainName);
+        segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
+            GrGLShaderVar::kUniform_TypeModifier, texDomainName);
         GrStringBuilder coordVar("clampCoord");
         segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
                                   float_vector_type_str(coordDims),
index 12f175f..450da05 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "GrDrawState.h"
 #include "GrGLInterface.h"
+#include "GrGLSL.h"
 #include "GrStringBuilder.h"
 #include "GrGpu.h"
 
@@ -36,22 +37,6 @@ struct ShaderCodeSegments;
  */
 class GrGLProgram {
 public:
-    // Limited set of GLSL versions we build shaders for. Caller should round
-    // down the GLSL version to one of these enums.
-    enum GLSLVersion {
-        /**
-         * Desktop GLSL 1.10 and ES2 shading lang (based on desktop GLSL 1.20)
-         */
-        k110_GLSLVersion,
-        /**
-         * Desktop GLSL 1.30
-         */
-        k130_GLSLVersion,
-        /**
-         * Dekstop GLSL 1.50
-         */
-        k150_GLSLVersion,
-    };
 
     class CachedData;
 
@@ -64,7 +49,7 @@ public:
      *  but in a separate cacheable container.
      */
     bool genProgram(const GrGLInterface* gl,
-                    GLSLVersion glslVersion,
+                    GrGLSLGeneration glslVersion,
                     CachedData* programData) const;
 
      /**
@@ -353,7 +338,7 @@ private:
                       StageUniLocations* locations) const;
 
     void genGeometryShader(const GrGLInterface* gl,
-                           GLSLVersion glslVersion,
+                           GrGLSLGeneration glslVersion,
                            ShaderCodeSegments* segments) const;
 
     // generates code to compute coverage based on edge AA.
@@ -364,7 +349,7 @@ private:
                          ShaderCodeSegments* segments) const;
 
     static bool CompileShaders(const GrGLInterface* gl,
-                               GLSLVersion glslVersion,
+                               GrGLSLGeneration glslVersion,
                                const ShaderCodeSegments& segments, 
                                CachedData* programData);
 
diff --git a/src/gpu/GrGLSL.cpp b/src/gpu/GrGLSL.cpp
new file mode 100644 (file)
index 0000000..1062c81
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrGLSL.h"
+
+GrGLSLGeneration GetGLSLGeneration(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;
+            } else if (ver >= GR_GLSL_VER(1,30)) {
+                return k130_GLSLGeneration;
+            } else {
+                return k110_GLSLGeneration;
+            }
+        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;
+        default:
+            GrCrash("Unknown GL Binding");
+            return k110_GLSLGeneration; // suppress warning
+    }
+}
+
diff --git a/src/gpu/GrGLSL.h b/src/gpu/GrGLSL.h
new file mode 100644 (file)
index 0000000..501d1ba
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2011 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrGLSL_DEFINED
+#define GrGLSL_DEFINED
+
+#include "GrGLInterface.h"
+
+// 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,
+    /**
+     * Desktop GLSL 1.30
+     */
+    k130_GLSLGeneration,
+    /**
+     * Dekstop GLSL 1.50
+     */
+    k150_GLSLGeneration,
+};
+
+GrGLSLGeneration GetGLSLGeneration(GrGLBinding binding,
+                                   const GrGLInterface* gl);
+
+#endif
+
index 1e278c2..5f1ba03 100644 (file)
@@ -10,6 +10,7 @@
 #define GrGLShaderVar_DEFINED
 
 #include "GrGLInterface.h"
+#include "GrGLSL.h"
 #include "GrStringBuilder.h"
 
 #define USE_UNIFORM_FLOAT_ARRAYS true
@@ -30,10 +31,24 @@ public:
     };
 
     /**
+     * Early versions of GLSL have Varying and Attribute; those are later
+     * deprecated, but we still need to know whether a Varying variable
+     * should be treated as In or Out.
+     */
+    enum TypeModifier {
+        kNone_TypeModifier,
+        kOut_TypeModifier,
+        kIn_TypeModifier,
+        kUniform_TypeModifier,
+        kAttribute_TypeModifier
+    };
+
+    /**
      * Defaults to a float with no precision specifier
      */
     GrGLShaderVar() {
         fType = kFloat_Type;
+        fTypeModifier = kNone_TypeModifier;
         fCount = kNonArray;
         fEmitPrecision = false;
         fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
@@ -41,6 +56,7 @@ public:
 
     GrGLShaderVar(const GrGLShaderVar& var)
         : fType(var.fType)
+        , fTypeModifier(var.fTypeModifier)
         , fName(var.fName)
         , fCount(var.fCount)
         , fEmitPrecision(var.fEmitPrecision)
@@ -58,10 +74,12 @@ public:
      * Sets as a non-array.
      */
     void set(Type type,
+             TypeModifier typeModifier,
              const GrStringBuilder& name,
              bool emitPrecision = false,
              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
         fType = type;
+        fTypeModifier = typeModifier;
         fName = name;
         fCount = kNonArray;
         fEmitPrecision = emitPrecision;
@@ -72,10 +90,12 @@ public:
      * Sets as a non-array.
      */
     void set(Type type,
+             TypeModifier typeModifier,
              const char* name,
              bool specifyPrecision = false,
              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
         fType = type;
+        fTypeModifier = typeModifier;
         fName = name;
         fCount = kNonArray;
         fEmitPrecision = specifyPrecision;
@@ -86,11 +106,13 @@ public:
      * Set all var options
      */
     void set(Type type,
+             TypeModifier typeModifier,
              const GrStringBuilder& name,
              int count,
              bool specifyPrecision = false,
              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
         fType = type;
+        fTypeModifier = typeModifier;
         fName = name;
         fCount = count;
         fEmitPrecision = specifyPrecision;
@@ -101,11 +123,13 @@ public:
      * Set all var options
      */
     void set(Type type,
+             TypeModifier typeModifier,
              const char* name,
              int count,
              bool specifyPrecision = false,
              bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
         fType = type;
+        fTypeModifier = typeModifier;
         fName = name;
         fCount = count;
         fEmitPrecision = specifyPrecision;
@@ -160,6 +184,9 @@ public:
      */
     void setType(Type type) { fType = type; }
 
+    TypeModifier getTypeModifier() const { return fTypeModifier; }
+    void setTypeModifier(TypeModifier type) { fTypeModifier = type; }
+
     /**
      * Must the variable declaration emit a precision specifier
      */
@@ -172,7 +199,12 @@ public:
     /**
      * Write a declaration of this variable to out.
      */
-    void appendDecl(const GrGLInterface* gl, GrStringBuilder* out) const {
+    void appendDecl(const GrGLInterface* gl, GrStringBuilder* out,
+                    GrGLSLGeneration gen) const {
+        if (this->getTypeModifier() != kNone_TypeModifier) {
+           out->append(TypeModifierString(this->getTypeModifier(), gen));
+           out->append(" ");
+        }
         if (this->emitsPrecision()) {
             out->append(PrecisionString(gl));
             out->append(" ");
@@ -195,6 +227,7 @@ public:
                          TypeString(effectiveType),
                          this->getName().c_str());
         }
+        out->append(";\n");
     }
 
     static const char* TypeString(Type t) {
@@ -236,7 +269,27 @@ private:
         return gl->supportsDesktop() ? "" : "mediump";
     }
 
+    static const char* TypeModifierString(TypeModifier t,
+                                          GrGLSLGeneration gen) {
+        switch (t) {
+            case kNone_TypeModifier:
+                return "";
+            case kOut_TypeModifier:
+                return k110_GLSLGeneration == gen ? "varying" : "out";
+            case kIn_TypeModifier:
+                return k110_GLSLGeneration == gen ? "varying" : "in";
+            case kUniform_TypeModifier:
+                return "uniform";
+            case kAttribute_TypeModifier:
+                return k110_GLSLGeneration == gen ? "attribute" : "in";
+            default:
+                GrCrash("Unknown shader variable type modifier.");
+                return ""; // suppress warning
+        }
+    }
+
     Type            fType;
+    TypeModifier    fTypeModifier;
     GrStringBuilder fName;
     int             fCount;
     bool            fEmitPrecision;
index 7b364e6..9018a4e 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "GrBinHashKey.h"
 #include "GrGLProgram.h"
+#include "GrGLSL.h"
 #include "GrGpuGLShaders.h"
 #include "GrGpuVertex.h"
 #include "GrNoncopyable.h"
@@ -55,15 +56,15 @@ private:
     int                         fCount;
     unsigned int                fCurrLRUStamp;
     const GrGLInterface*        fGL;
-    GrGLProgram::GLSLVersion    fGLSLVersion;
+    GrGLSLGeneration            fGLSLGeneration;
 
 public:
     ProgramCache(const GrGLInterface* gl,
-                 GrGLProgram::GLSLVersion glslVersion) 
+                 GrGLSLGeneration glslGeneration) 
         : fCount(0)
         , fCurrLRUStamp(0)
         , fGL(gl)
-        , fGLSLVersion(glslVersion) {
+        , fGLSLGeneration(glslGeneration) {
     }
 
     ~ProgramCache() {
@@ -89,7 +90,8 @@ public:
         
         Entry* entry = fHashCache.find(newEntry.fKey);
         if (NULL == entry) {
-            if (!desc.genProgram(fGL, fGLSLVersion, &newEntry.fProgramData)) {
+            if (!desc.genProgram(fGL, fGLSLGeneration,
+                                 &newEntry.fProgramData)) {
                 return NULL;
             }
             if (fCount < kMaxEntries) {
@@ -144,29 +146,6 @@ void GrGpuGLShaders::DeleteProgram(const GrGLInterface* gl,
 
 namespace {
 
-GrGLProgram::GLSLVersion get_glsl_version(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 GrGLProgram::k150_GLSLVersion;
-            } else if (ver >= GR_GLSL_VER(1,30)) {
-                return GrGLProgram::k130_GLSLVersion;
-            } else {
-                return GrGLProgram::k110_GLSLVersion;
-            }
-        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 GrGLProgram::k110_GLSLVersion;
-        default:
-            GrCrash("Unknown GL Binding");
-            return GrGLProgram::k110_GLSLVersion; // suppress warning
-    }
-}
-
 // GrRandoms nextU() values have patterns in the low bits
 // So using nextU() % array_count might never take some values.
 int random_int(GrRandom* r, int count) {
@@ -186,8 +165,8 @@ bool random_bool(GrRandom* r) {
 
 bool GrGpuGLShaders::programUnitTest() {
 
-    GrGLProgram::GLSLVersion glslVersion = 
-            get_glsl_version(this->glBinding(), this->glInterface());
+    GrGLSLGeneration glslGeneration = 
+            GetGLSLGeneration(this->glBinding(), this->glInterface());
     static const int STAGE_OPTS[] = {
         0,
         StageDesc::kNoPerspective_OptFlagBit,
@@ -302,7 +281,7 @@ bool GrGpuGLShaders::programUnitTest() {
         }
         CachedData cachedData;
         if (!program.genProgram(this->glInterface(),
-                                glslVersion,
+                                glslGeneration,
                                 &cachedData)) {
             return false;
         }
@@ -325,8 +304,8 @@ GrGLBinding get_binding_in_use(const GrGLInterface* gl) {
 GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
     : GrGpuGL(gl, get_binding_in_use(gl)) {
 
-    GrGLProgram::GLSLVersion glslVersion =
-        get_glsl_version(this->glBinding(), gl);
+    GrGLSLGeneration glslGeneration =
+        GetGLSLGeneration(this->glBinding(), gl);
 
     // Enable supported shader-releated caps
     fCaps.fShaderSupport = true;
@@ -339,7 +318,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) &&
-                                glslVersion >= GrGLProgram::k150_GLSLVersion;
+                                glslGeneration >= k150_GLSLGeneration;
     } else {
         fCaps.fShaderDerivativeSupport =
                             this->hasExtension("GL_OES_standard_derivatives");
@@ -348,7 +327,7 @@ GrGpuGLShaders::GrGpuGLShaders(const GrGLInterface* gl)
     GR_GL_GetIntegerv(gl, GR_GL_MAX_VERTEX_ATTRIBS, &fMaxVertexAttribs);
 
     fProgramData = NULL;
-    fProgramCache = new ProgramCache(gl, glslVersion);
+    fProgramCache = new ProgramCache(gl, glslGeneration);
 
 #if 0
     this->programUnitTest();