From: tomhudson@google.com Date: Thu, 8 Dec 2011 14:44:10 +0000 (+0000) Subject: Make GrGLShaderVar objects aware of whether they are uniform, varying, or X-Git-Tag: accepted/tizen/5.0/unified/20181102.025319~17169 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=086e5354fe7ae60e69c42bdfbc3d03bd8559b44f;p=platform%2Fupstream%2FlibSkiaSharp.git Make GrGLShaderVar objects aware of whether they are uniform, varying, or 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 --- diff --git a/gyp/gpu.gyp b/gyp/gpu.gyp index f0173f7..9fcded1 100644 --- a/gyp/gpu.gyp +++ b/gyp/gpu.gyp @@ -210,6 +210,8 @@ '../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', diff --git a/src/gpu/GrGLProgram.cpp b/src/gpu/GrGLProgram.cpp index 9395c0e..b7e902d 100644 --- a/src/gpu/GrGLProgram.cpp +++ b/src/gpu/GrGLProgram.cpp @@ -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), diff --git a/src/gpu/GrGLProgram.h b/src/gpu/GrGLProgram.h index 12f175f..450da05 100644 --- a/src/gpu/GrGLProgram.h +++ b/src/gpu/GrGLProgram.h @@ -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 index 0000000..1062c81 --- /dev/null +++ b/src/gpu/GrGLSL.cpp @@ -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 index 0000000..501d1ba --- /dev/null +++ b/src/gpu/GrGLSL.h @@ -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 + diff --git a/src/gpu/GrGLShaderVar.h b/src/gpu/GrGLShaderVar.h index 1e278c2..5f1ba03 100644 --- a/src/gpu/GrGLShaderVar.h +++ b/src/gpu/GrGLShaderVar.h @@ -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; diff --git a/src/gpu/GrGpuGLShaders.cpp b/src/gpu/GrGpuGLShaders.cpp index 7b364e6..9018a4e 100644 --- a/src/gpu/GrGpuGLShaders.cpp +++ b/src/gpu/GrGpuGLShaders.cpp @@ -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();