Resubmit 2289 with fix for glsl version
git-svn-id: http://skia.googlecode.com/svn/trunk@2291 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrGLProgram.cpp b/gpu/src/GrGLProgram.cpp
index 0efb99f..27eb367 100644
--- a/gpu/src/GrGLProgram.cpp
+++ b/gpu/src/GrGLProgram.cpp
@@ -9,8 +9,8 @@
#include "GrGLProgram.h"
-#include "GrGLConfig.h"
-
+#include "GrAllocator.h"
+#include "GrGLShaderVar.h"
#include "SkTrace.h"
#include "SkXfermode.h"
@@ -36,6 +36,32 @@
#define PRINT_SHADERS 0
+typedef GrTAllocator<GrGLShaderVar> VarArray;
+
+// number of each input/output type in a single allocation block
+static const int gVarsPerBlock = 8;
+// except FS outputs where we expect 2 at most.
+static const int gMaxFSOutputs = 2;
+
+struct ShaderCodeSegments {
+ ShaderCodeSegments()
+ : fVSUnis(gVarsPerBlock)
+ , fVSAttrs(gVarsPerBlock)
+ , fVaryings(gVarsPerBlock)
+ , fFSUnis(gVarsPerBlock)
+ , fFSOutputs(gMaxFSOutputs) {}
+ GrStringBuilder fHeader; // VS+FS, GLSL version, etc
+ VarArray fVSUnis;
+ VarArray fVSAttrs;
+ VarArray fVaryings;
+ VarArray fFSUnis;
+ VarArray fFSOutputs;
+ GrStringBuilder fFSFunctions;
+ GrStringBuilder fVSCode;
+ GrStringBuilder fFSCode;
+};
+
+
#if GR_GL_ATTRIBUTE_MATRICES
#define VIEW_MATRIX_NAME "aViewM"
#else
@@ -49,53 +75,61 @@
#define EDGES_UNI_NAME "uEdges"
#define COL_FILTER_UNI_NAME "uColorFilter"
-static inline void tex_attr_name(int coordIdx, GrStringBuilder* s) {
+namespace {
+inline void tex_attr_name(int coordIdx, GrStringBuilder* s) {
*s = "aTexCoord";
s->appendS32(coordIdx);
}
-static inline const char* float_vector_type(int count) {
- static const char* FLOAT_VECS[] = {"ERROR", "float", "vec2", "vec3", "vec4"};
- GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(FLOAT_VECS));
- return FLOAT_VECS[count];
+inline GrGLShaderVar::Type float_vector_type(int count) {
+ GR_STATIC_ASSERT(GrGLShaderVar::kFloat_Type == 0);
+ GR_STATIC_ASSERT(GrGLShaderVar::kVec2f_Type == 1);
+ GR_STATIC_ASSERT(GrGLShaderVar::kVec3f_Type == 2);
+ GR_STATIC_ASSERT(GrGLShaderVar::kVec4f_Type == 3);
+ GrAssert(count > 0 && count <= 4);
+ return (GrGLShaderVar::Type)(count - 1);
}
-static inline const char* vector_homog_coord(int count) {
+inline const char* float_vector_type_str(int count) {
+ return GrGLShaderVar::TypeString(float_vector_type(count));
+}
+
+inline const char* vector_homog_coord(int count) {
static const char* HOMOGS[] = {"ERROR", "", ".y", ".z", ".w"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(HOMOGS));
return HOMOGS[count];
}
-static inline const char* vector_nonhomog_coords(int count) {
+inline const char* vector_nonhomog_coords(int count) {
static const char* NONHOMOGS[] = {"ERROR", "", ".x", ".xy", ".xyz"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(NONHOMOGS));
return NONHOMOGS[count];
}
-static inline const char* vector_all_coords(int count) {
+inline const char* vector_all_coords(int count) {
static const char* ALL[] = {"ERROR", "", ".xy", ".xyz", ".xyzw"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ALL));
return ALL[count];
}
-static inline const char* all_ones_vec(int count) {
+inline const char* all_ones_vec(int count) {
static const char* ONESVEC[] = {"ERROR", "1.0", "vec2(1,1)",
"vec3(1,1,1)", "vec4(1,1,1,1)"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ONESVEC));
return ONESVEC[count];
}
-static inline const char* all_zeros_vec(int count) {
+inline const char* all_zeros_vec(int count) {
static const char* ZEROSVEC[] = {"ERROR", "0.0", "vec2(0,0)",
"vec3(0,0,0)", "vec4(0,0,0,0)"};
GrAssert(count >= 1 && count < (int)GR_ARRAY_COUNT(ZEROSVEC));
return ZEROSVEC[count];
}
-static inline const char* declared_color_output_name() { return "fsColorOut"; }
-static inline const char* dual_source_output_name() { return "dualSourceOut"; }
+inline const char* declared_color_output_name() { return "fsColorOut"; }
+inline const char* dual_source_output_name() { return "dualSourceOut"; }
-static void tex_matrix_name(int stage, GrStringBuilder* s) {
+inline void tex_matrix_name(int stage, GrStringBuilder* s) {
#if GR_GL_ATTRIBUTE_MATRICES
*s = "aTexM";
#else
@@ -104,42 +138,43 @@
s->appendS32(stage);
}
-static void normalized_texel_size_name(int stage, GrStringBuilder* s) {
+inline void normalized_texel_size_name(int stage, GrStringBuilder* s) {
*s = "uTexelSize";
s->appendS32(stage);
}
-static void sampler_name(int stage, GrStringBuilder* s) {
+inline void sampler_name(int stage, GrStringBuilder* s) {
*s = "uSampler";
s->appendS32(stage);
}
-static void stage_varying_name(int stage, GrStringBuilder* s) {
+inline void stage_varying_name(int stage, GrStringBuilder* s) {
*s = "vStage";
s->appendS32(stage);
}
-static void radial2_param_name(int stage, GrStringBuilder* s) {
+inline void radial2_param_name(int stage, GrStringBuilder* s) {
*s = "uRadial2Params";
s->appendS32(stage);
}
-static void radial2_varying_name(int stage, GrStringBuilder* s) {
+inline void radial2_varying_name(int stage, GrStringBuilder* s) {
*s = "vB";
s->appendS32(stage);
}
-static void convolve_param_names(int stage, GrStringBuilder* k, GrStringBuilder* i) {
+inline void convolve_param_names(int stage, GrStringBuilder* k, GrStringBuilder* i) {
*k = "uKernel";
k->appendS32(stage);
*i = "uImageIncrement";
i->appendS32(stage);
}
-static void tex_domain_name(int stage, GrStringBuilder* s) {
+inline void tex_domain_name(int stage, GrStringBuilder* s) {
*s = "uTexDom";
s->appendS32(stage);
}
+}
GrGLProgram::GrGLProgram() {
}
@@ -321,15 +356,39 @@
add_helper(outputVar, colorStr.c_str(), constStr.c_str(), fsCode);
}
+namespace {
+
+const char* glsl_version_string(const GrGLInterface* gl,
+ GrGLProgram::GLSLVersion v) {
+ switch (v) {
+ case GrGLProgram::k120_GLSLVersion:
+ if (gl->supportsES()) {
+ // 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 120\n";
+ }
+ case GrGLProgram::k130_GLSLVersion:
+ GrAssert(!gl->supportsES());
+ return "#version 130\n";
+ default:
+ GrCrash("Unknown GL version.");
+ return ""; // suppress warning
+ }
+}
+
+}
+
void GrGLProgram::genEdgeCoverage(const GrGLInterface* gl,
GrVertexLayout layout,
CachedData* programData,
GrStringBuilder* coverageVar,
ShaderCodeSegments* segments) const {
if (fProgramDesc.fEdgeAANumEdges > 0) {
- segments->fFSUnis.append("uniform vec3 " EDGES_UNI_NAME "[");
- segments->fFSUnis.appendS32(fProgramDesc.fEdgeAANumEdges);
- segments->fFSUnis.append("];\n");
+ segments->fFSUnis.push_back().set(GrGLShaderVar::kVec3f_Type,
+ EDGES_UNI_NAME,
+ fProgramDesc.fEdgeAANumEdges);
programData->fUniLocations.fEdgesUni = kUseUniform;
int count = fProgramDesc.fEdgeAANumEdges;
segments->fFSCode.append(
@@ -376,8 +435,8 @@
}
*coverageVar = "edgeAlpha";
} else if (layout & GrDrawTarget::kEdge_VertexLayoutBit) {
- segments->fVSAttrs.append("attribute vec4 " EDGE_ATTR_NAME ";\n");
- segments->fVaryings.append("varying vec4 vEdge;\n");
+ segments->fVaryings.push_back().set(GrGLShaderVar::kVec4f_Type, "vEdge");
+ segments->fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type, EDGE_ATTR_NAME);
segments->fVSCode.append("\tvEdge = " EDGE_ATTR_NAME ";\n");
if (GrDrawTarget::kHairLine_EdgeType == fProgramDesc.fVertexEdgeType) {
segments->fFSCode.append("\tfloat edgeAlpha = abs(dot(vec3(gl_FragCoord.xy,1), vEdge.xyz));\n");
@@ -402,7 +461,33 @@
}
}
-bool GrGLProgram::genProgram(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,
+ VarArray* fsOutputs,
+ const char** name) {
+ switch (v) {
+ case GrGLProgram::k120_GLSLVersion:
+ *name = "gl_FragColor";
+ return false;
+ break;
+ case GrGLProgram::k130_GLSLVersion:
+ *name = declared_color_output_name();
+ fsOutputs->push_back().set(GrGLShaderVar::kVec4f_Type,
+ declared_color_output_name());
+ return true;
+ break;
+ default:
+ GrCrash("Unknown GLSL version.");
+ return false; // suppress warning
+ }
+}
+
+}
+
+bool GrGLProgram::genProgram(const GrGLInterface* gl,
+ GLSLVersion glslVersion,
GrGLProgram::CachedData* programData) const {
ShaderCodeSegments segments;
@@ -432,25 +517,19 @@
// declare an output, which is incompatible with gl_FragColor/gl_FragData.
const char* fsColorOutput;
bool dualSourceOutputWritten = false;
- bool usingDeclaredOutputs = ProgramDesc::kNone_DualSrcOutput !=
- fProgramDesc.fDualSrcOutput;
- if (usingDeclaredOutputs) {
- GrAssert(0 == segments.fHeader.size());
- segments.fHeader.printf("#version 150\n");
- fsColorOutput = declared_color_output_name();
- segments.fFSOutputs.appendf("out vec4 %s;\n", fsColorOutput);
- } else {
- fsColorOutput = "gl_FragColor";
- }
+ segments.fHeader.printf(glsl_version_string(gl, glslVersion));
+ bool isColorDeclared = decl_and_get_fs_color_output(glslVersion,
+ &segments.fFSOutputs,
+ &fsColorOutput);
#if GR_GL_ATTRIBUTE_MATRICES
- segments.fVSAttrs += "attribute mat3 " VIEW_MATRIX_NAME ";\n";
+ segments.fVSAttrs.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
programData->fUniLocations.fViewMatrixUni = kSetAsAttribute;
#else
- segments.fVSUnis += "uniform mat3 " VIEW_MATRIX_NAME ";\n";
+ segments.fVSUnis.push_back().set(GrGLShaderVar::kMat33f_Type, VIEW_MATRIX_NAME);
programData->fUniLocations.fViewMatrixUni = kUseUniform;
#endif
- segments.fVSAttrs += "attribute vec2 " POS_ATTR_NAME ";\n";
+ segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type, POS_ATTR_NAME);
segments.fVSCode.append(
"void main() {\n"
@@ -463,13 +542,16 @@
if (needComputedColor) {
switch (fProgramDesc.fColorType) {
case ProgramDesc::kAttribute_ColorType:
- segments.fVSAttrs.append( "attribute vec4 " COL_ATTR_NAME ";\n");
- segments.fVaryings.append("varying vec4 vColor;\n");
- segments.fVSCode.append( "\tvColor = " COL_ATTR_NAME ";\n");
+ segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec4f_Type,
+ COL_ATTR_NAME);
+ segments.fVaryings.push_back().set(GrGLShaderVar::kVec4f_Type,
+ "vColor");
+ segments.fVSCode.append("\tvColor = " COL_ATTR_NAME ";\n");
inColor = "vColor";
break;
case ProgramDesc::kUniform_ColorType:
- segments.fFSUnis.append( "uniform vec4 " COL_UNI_NAME ";\n");
+ segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
+ COL_UNI_NAME);
programData->fUniLocations.fColorUni = kUseUniform;
inColor = COL_UNI_NAME;
break;
@@ -490,7 +572,8 @@
for (int t = 0; t < GrDrawTarget::kMaxTexCoords; ++t) {
if (GrDrawTarget::VertexUsesTexCoordIdx(t, layout)) {
tex_attr_name(t, texCoordAttrs + t);
- segments.fVSAttrs.appendf("attribute vec2 %s;\n", texCoordAttrs[t].c_str());
+ segments.fVSAttrs.push_back().set(GrGLShaderVar::kVec2f_Type,
+ texCoordAttrs[t].c_str());
}
}
@@ -521,7 +604,8 @@
inCoords = texCoordAttrs[tcIdx].c_str();
}
- genStageCode(gl, s,
+ genStageCode(gl,
+ s,
fProgramDesc.fStages[s],
inColor.size() ? inColor.c_str() : NULL,
outColor.c_str(),
@@ -544,7 +628,8 @@
&needColorFilterUniform, &bogus);
}
if (needColorFilterUniform) {
- segments.fFSUnis.append( "uniform vec4 " COL_FILTER_UNI_NAME ";\n");
+ segments.fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type,
+ COL_FILTER_UNI_NAME);
programData->fUniLocations.fColorFilterUni = kUseUniform;
}
@@ -608,8 +693,8 @@
}
}
if (ProgramDesc::kNone_DualSrcOutput != fProgramDesc.fDualSrcOutput) {
- segments.fFSOutputs.appendf("out vec4 %s;\n",
- dual_source_output_name());
+ segments.fFSOutputs.push_back().set(GrGLShaderVar::kVec4f_Type,
+ dual_source_output_name());
bool outputIsZero = false;
GrStringBuilder coeff;
if (ProgramDesc::kCoverage_DualSrcOutput !=
@@ -644,9 +729,9 @@
if (!wroteFragColorZero) {
modulate_helper(fsColorOutput,
- inColor.c_str(),
- inCoverage.c_str(),
- &segments.fFSCode);
+ inColor.c_str(),
+ inCoverage.c_str(),
+ &segments.fFSCode);
}
segments.fVSCode.append("}\n");
@@ -655,12 +740,12 @@
///////////////////////////////////////////////////////////////////////////
// compile and setup attribs and unis
- if (!CompileFSAndVS(gl, segments, programData)) {
+ if (!CompileFSAndVS(gl, glslVersion, segments, programData)) {
return false;
}
if (!this->bindOutputsAttribsAndLinkProgram(gl, texCoordAttrs,
- usingDeclaredOutputs,
+ isColorDeclared,
dualSourceOutputWritten,
programData)) {
return false;
@@ -671,7 +756,36 @@
return true;
}
+namespace {
+
+void expand_decls(const VarArray& unis,
+ const GrGLInterface* gl,
+ const char* prefix,
+ GrStringBuilder* string) {
+ const int count = unis.count();
+ for (int i = 0; i < count; ++i) {
+ string->append(prefix);
+ string->append(" ");
+ unis[i].appendDecl(gl, string);
+ string->append(";\n");
+ }
+}
+
+void print_shader(int stringCnt,
+ const char** strings,
+ int* stringLengths) {
+ for (int i = 0; i < stringCnt; ++i) {
+ if (NULL == stringLengths || stringLengths[i] < 0) {
+ GrPrintf(strings[i]);
+ } else {
+ GrPrintf("%.*s", stringLengths[i], strings[i]);
+ }
+ }
+}
+}
+
bool GrGLProgram::CompileFSAndVS(const GrGLInterface* gl,
+ GLSLVersion glslVersion,
const ShaderCodeSegments& segments,
CachedData* programData) {
@@ -679,25 +793,41 @@
const char* strings[MAX_STRINGS];
int lengths[MAX_STRINGS];
int stringCnt = 0;
+ GrStringBuilder attrs;
+ GrStringBuilder varyings;
+ GrStringBuilder unis;
+ GrStringBuilder fsOutputs;
+
+ static const char* gVaryingPrefixes[2][2] = {{"varying", "varying"},
+ {"out", "in"}};
+ const char** varyingPrefixes = glslVersion == k120_GLSLVersion ?
+ gVaryingPrefixes[0] :
+ gVaryingPrefixes[1];
+ const char* attributePrefix = glslVersion == k120_GLSLVersion ?
+ "attribute" :
+ "in";
if (segments.fHeader.size()) {
strings[stringCnt] = segments.fHeader.c_str();
lengths[stringCnt] = segments.fHeader.size();
++stringCnt;
}
- if (segments.fVSUnis.size()) {
- strings[stringCnt] = segments.fVSUnis.c_str();
- lengths[stringCnt] = segments.fVSUnis.size();
+ expand_decls(segments.fVSUnis, gl, "uniform", &unis);
+ if (unis.size()) {
+ strings[stringCnt] = unis.c_str();
+ lengths[stringCnt] = unis.size();
++stringCnt;
}
- if (segments.fVSAttrs.size()) {
- strings[stringCnt] = segments.fVSAttrs.c_str();
- lengths[stringCnt] = segments.fVSAttrs.size();
+ expand_decls(segments.fVSAttrs, gl, attributePrefix, &attrs);
+ if (attrs.size()) {
+ strings[stringCnt] = attrs.c_str();
+ lengths[stringCnt] = attrs.size();
++stringCnt;
}
- if (segments.fVaryings.size()) {
- strings[stringCnt] = segments.fVaryings.c_str();
- lengths[stringCnt] = segments.fVaryings.size();
+ expand_decls(segments.fVaryings, gl, varyingPrefixes[0], &varyings);
+ if (varyings.size()) {
+ strings[stringCnt] = varyings.c_str();
+ lengths[stringCnt] = varyings.size();
++stringCnt;
}
@@ -707,13 +837,10 @@
++stringCnt;
#if PRINT_SHADERS
- GrPrintf(segments.fHeader.c_str());
- GrPrintf(segments.fVSUnis.c_str());
- GrPrintf(segments.fVSAttrs.c_str());
- GrPrintf(segments.fVaryings.c_str());
- GrPrintf(segments.fVSCode.c_str());
+ print_shader(stringCnt, strings, lengths);
GrPrintf("\n");
#endif
+
GrAssert(stringCnt <= MAX_STRINGS);
programData->fVShaderID = CompileShader(gl, GR_GL_VERTEX_SHADER,
stringCnt, strings, lengths);
@@ -734,19 +861,26 @@
lengths[stringCnt] = strlen(GrShaderPrecision(gl));
++stringCnt;
}
- if (segments.fFSUnis.size()) {
- strings[stringCnt] = segments.fFSUnis.c_str();
- lengths[stringCnt] = segments.fFSUnis.size();
+ unis.reset();
+ expand_decls(segments.fFSUnis, gl, "uniform", &unis);
+ if (unis.size()) {
+ strings[stringCnt] = unis.c_str();
+ lengths[stringCnt] = unis.size();
++stringCnt;
}
- if (segments.fVaryings.size()) {
- strings[stringCnt] = segments.fVaryings.c_str();
- lengths[stringCnt] = segments.fVaryings.size();
+ varyings.reset();
+ expand_decls(segments.fVaryings, gl, varyingPrefixes[1], &varyings);
+ if (varyings.size()) {
+ strings[stringCnt] = varyings.c_str();
+ lengths[stringCnt] = varyings.size();
++stringCnt;
}
- if (segments.fFSOutputs.size()) {
- strings[stringCnt] = segments.fFSOutputs.c_str();
- lengths[stringCnt] = segments.fFSOutputs.size();
+ expand_decls(segments.fFSOutputs, gl, "out", &fsOutputs);
+ if (fsOutputs.size()) {
+ // We shouldn't have declared outputs on 1.2
+ GrAssert(k120_GLSLVersion != glslVersion);
+ strings[stringCnt] = fsOutputs.c_str();
+ lengths[stringCnt] = fsOutputs.size();
++stringCnt;
}
if (segments.fFSFunctions.size()) {
@@ -761,15 +895,10 @@
++stringCnt;
#if PRINT_SHADERS
- GrPrintf(segments.fHeader.c_str());
- GrPrintf(GrShaderPrecision(gl));
- GrPrintf(segments.fFSUnis.c_str());
- GrPrintf(segments.fVaryings.c_str());
- GrPrintf(segments.fFSOutputs.c_str());
- GrPrintf(segments.fFSFunctions.c_str());
- GrPrintf(segments.fFSCode.c_str());
+ print_shader(stringCnt, strings, lengths);
GrPrintf("\n");
#endif
+
GrAssert(stringCnt <= MAX_STRINGS);
programData->fFShaderID = CompileShader(gl, GR_GL_FRAGMENT_SHADER,
stringCnt, strings, lengths);
@@ -810,13 +939,7 @@
GrGLsizei length = GR_GL_INIT_ZERO;
GR_GL_CALL(gl, GetShaderInfoLog(shader, infoLen+1,
&length, (char*)log.get()));
- for (int i = 0; i < stringCnt; ++i) {
- if (NULL == stringLengths || stringLengths[i] < 0) {
- GrPrintf(strings[i]);
- } else {
- GrPrintf("%.*s", stringLengths[i], strings[i]);
- }
- }
+ print_shader(stringCnt, strings, stringLengths);
GrPrintf("\n%s", log.get());
}
GrAssert(!"Shader compilation failed!");
@@ -1027,9 +1150,6 @@
GrAssert(stageNum >= 0 && stageNum <= 9);
- GrStringBuilder varyingName;
- stage_varying_name(stageNum, &varyingName);
-
// First decide how many coords are needed to access the texture
// Right now it's always 2 but we could start using 1D textures for
// gradients.
@@ -1039,18 +1159,22 @@
// decide whether we need a matrix to transform texture coords
// and whether the varying needs a perspective coord.
- GrStringBuilder texMName;
- tex_matrix_name(stageNum, &texMName);
+ const char* matName = NULL;
if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
varyingDims = coordDims;
} else {
+ GrGLShaderVar* mat;
#if GR_GL_ATTRIBUTE_MATRICES
- segments->fVSAttrs.appendf("attribute mat3 %s;\n", texMName.c_str());
+ mat = &segments->fVSAttrs.push_back();
locations->fTextureMatrixUni = kSetAsAttribute;
#else
- segments->fVSUnis.appendf("uniform mat3 %s;\n", texMName.c_str());
+ mat = &segments->fVSUnis.push_back();
locations->fTextureMatrixUni = kUseUniform;
#endif
+ tex_matrix_name(stageNum, mat->accessName());
+ mat->setType(GrGLShaderVar::kMat33f_Type);
+ matName = mat->getName().c_str();
+
if (desc.fOptFlags & StageDesc::kNoPerspective_OptFlagBit) {
varyingDims = coordDims;
} else {
@@ -1058,75 +1182,93 @@
}
}
- GrStringBuilder samplerName;
- sampler_name(stageNum, &samplerName);
- segments->fFSUnis.appendf("uniform sampler2D %s;\n", samplerName.c_str());
+ segments->fFSUnis.push_back().setType(GrGLShaderVar::kSampler2D_Type);
+ sampler_name(stageNum, segments->fFSUnis.back().accessName());
locations->fSamplerUni = kUseUniform;
+ const char* samplerName = segments->fFSUnis.back().getName().c_str();
- GrStringBuilder texelSizeName;
+ const char* texelSizeName = NULL;
if (StageDesc::k2x2_FetchMode == desc.fFetchMode) {
- normalized_texel_size_name(stageNum, &texelSizeName);
- segments->fFSUnis.appendf("uniform vec2 %s;\n", texelSizeName.c_str());
+ segments->fFSUnis.push_back().setType(GrGLShaderVar::kVec2f_Type);
+ normalized_texel_size_name(stageNum, segments->fFSUnis.back().accessName());
+ texelSizeName = segments->fFSUnis.back().getName().c_str();
}
- segments->fVaryings.appendf("varying %s %s;\n",
- float_vector_type(varyingDims), varyingName.c_str());
+ const char* varyingName;
+ GrGLShaderVar* varying = &segments->fVaryings.push_back();
+ stage_varying_name(stageNum, varying->accessName());
+ varying->setType(float_vector_type(varyingDims));
+ varyingName = varying->getName().c_str();
- if (desc.fOptFlags & StageDesc::kIdentityMatrix_OptFlagBit) {
+ if (!matName) {
GrAssert(varyingDims == coordDims);
- segments->fVSCode.appendf("\t%s = %s;\n", varyingName.c_str(), vsInCoord);
+ segments->fVSCode.appendf("\t%s = %s;\n", varyingName, vsInCoord);
} else {
// varying = texMatrix * texCoord
segments->fVSCode.appendf("\t%s = (%s * vec3(%s, 1))%s;\n",
- varyingName.c_str(), texMName.c_str(),
- vsInCoord, vector_all_coords(varyingDims));
+ varyingName, matName, vsInCoord,
+ vector_all_coords(varyingDims));
}
- GrStringBuilder radial2ParamsName;
- radial2_param_name(stageNum, &radial2ParamsName);
- // for radial grads without perspective we can pass the linear
- // part of the quadratic as a varying.
- GrStringBuilder radial2VaryingName;
- radial2_varying_name(stageNum, &radial2VaryingName);
+ const char* radial2ParamsName = NULL;
+ const char* radial2VaryingName = NULL;
- if (StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping ||
+ if (StageDesc::kRadial2Gradient_CoordMapping == desc.fCoordMapping ||
StageDesc::kRadial2GradientDegenerate_CoordMapping == desc.fCoordMapping) {
- segments->fVSUnis.appendf("uniform %s float %s[6];\n",
- GrPrecision(gl), radial2ParamsName.c_str());
- segments->fFSUnis.appendf("uniform float %s[6];\n",
- radial2ParamsName.c_str());
+ GrGLShaderVar* radial2FSParams = &segments->fFSUnis.push_back();
+ radial2FSParams->setType(GrGLShaderVar::kFloat_Type);
+ radial2FSParams->setArrayCount(6);
+ radial2_param_name(stageNum, radial2FSParams->accessName());
+ segments->fVSUnis.push_back(*radial2FSParams).setEmitPrecision(true);
+ radial2ParamsName = radial2FSParams->getName().c_str();
+
locations->fRadial2Uni = kUseUniform;
- // if there is perspective we don't interpolate this
+ // for radial grads without perspective we can pass the linear
+ // part of the quadratic as a varying.
if (varyingDims == coordDims) {
GrAssert(2 == coordDims);
- segments->fVaryings.appendf("varying float %s;\n", radial2VaryingName.c_str());
+
+ GrGLShaderVar* radial2Varying = &segments->fVaryings.push_back();
+ radial2Varying->setType(GrGLShaderVar::kFloat_Type);
+ radial2_varying_name(stageNum, radial2Varying->accessName());
+ radial2VaryingName = radial2Varying->getName().c_str();
// r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
+ const char* r2ParamName = radial2FSParams->getName().c_str();
+ const char* r2VarName = radial2Varying->getName().c_str();
segments->fVSCode.appendf("\t%s = 2.0 *(%s[2] * %s.x - %s[3]);\n",
- radial2VaryingName.c_str(), radial2ParamsName.c_str(),
- varyingName.c_str(), radial2ParamsName.c_str());
+ r2VarName, r2ParamName, varyingName,
+ r2ParamName);
}
}
- GrStringBuilder kernelName, kernelWidthName, imageIncrementName;
- convolve_param_names(stageNum, &kernelName, &imageIncrementName);
-
+ const char* kernelName = NULL;
+ const char* imageIncrementName = NULL;
if (ProgramDesc::StageDesc::kConvolution_FetchMode == desc.fFetchMode) {
- segments->fFSUnis.appendf("uniform float %s[%d];\n",
- kernelName.c_str(), desc.fKernelWidth);
- segments->fFSUnis.appendf("uniform vec2 %s;\n",
- imageIncrementName.c_str());
- segments->fVSUnis.appendf("uniform %s vec2 %s;\n",
- GrPrecision(gl),
- imageIncrementName.c_str());
+
+ GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
+ kernel->setType(GrGLShaderVar::kFloat_Type);
+ kernel->setArrayCount(desc.fKernelWidth);
+ GrGLShaderVar* imgInc = &segments->fFSUnis.push_back();
+ imgInc->setType(GrGLShaderVar::kVec2f_Type);
+
+ convolve_param_names(stageNum,
+ kernel->accessName(),
+ imgInc->accessName());
+ kernelName = kernel->getName().c_str();
+ imageIncrementName = imgInc->getName().c_str();
+
+ // need image increment in both VS and FS
+ segments->fVSUnis.push_back(*imgInc).setEmitPrecision(true);
+
locations->fKernelUni = kUseUniform;
locations->fImageIncrementUni = kUseUniform;
float scale = (desc.fKernelWidth - 1) * 0.5f;
segments->fVSCode.appendf("\t%s -= vec2(%g, %g) * %s;\n",
- varyingName.c_str(), scale, scale,
- imageIncrementName.c_str());
+ varyingName, scale, scale,
+ imageIncrementName);
}
/// Fragment Shader Stuff
@@ -1149,12 +1291,12 @@
fsCoordName = "inCoord";
fsCoordName.appendS32(stageNum);
segments->fFSCode.appendf("\t%s %s = %s%s / %s%s;\n",
- float_vector_type(coordDims),
- fsCoordName.c_str(),
- varyingName.c_str(),
- vector_nonhomog_coords(varyingDims),
- varyingName.c_str(),
- vector_homog_coord(varyingDims));
+ GrGLShaderVar::TypeString(float_vector_type(coordDims)),
+ fsCoordName.c_str(),
+ varyingName,
+ vector_nonhomog_coords(varyingDims),
+ varyingName,
+ vector_homog_coord(varyingDims));
}
}
@@ -1192,18 +1334,18 @@
bVar = "b";
bVar.appendS32(stageNum);
segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
- bVar.c_str(), radial2ParamsName.c_str(),
- fsCoordName.c_str(), radial2ParamsName.c_str());
+ bVar.c_str(), radial2ParamsName,
+ fsCoordName.c_str(), radial2ParamsName);
}
// c = (x^2)+(y^2) - params[4]
segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
cName.c_str(), fsCoordName.c_str(),
fsCoordName.c_str(),
- radial2ParamsName.c_str());
+ radial2ParamsName);
// ac4 = 4.0 * params[0] * c
segments->fFSCode.appendf("\tfloat %s = %s[0] * 4.0 * %s;\n",
- ac4Name.c_str(), radial2ParamsName.c_str(),
+ ac4Name.c_str(), radial2ParamsName,
cName.c_str());
// root = sqrt(b^2-4ac)
@@ -1215,8 +1357,8 @@
// x coord is: (-b + params[5] * sqrt(b^2-4ac)) * params[1]
// y coord is 0.5 (texture is effectively 1D)
sampleCoords.printf("vec2((-%s + %s[5] * %s) * %s[1], 0.5)",
- bVar.c_str(), radial2ParamsName.c_str(),
- rootName.c_str(), radial2ParamsName.c_str());
+ bVar.c_str(), radial2ParamsName,
+ rootName.c_str(), radial2ParamsName);
complexCoord = true;
break;}
case StageDesc::kRadial2GradientDegenerate_CoordMapping: {
@@ -1235,15 +1377,15 @@
bVar = "b";
bVar.appendS32(stageNum);
segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
- bVar.c_str(), radial2ParamsName.c_str(),
- fsCoordName.c_str(), radial2ParamsName.c_str());
+ bVar.c_str(), radial2ParamsName,
+ fsCoordName.c_str(), radial2ParamsName);
}
// c = (x^2)+(y^2) - params[4]
segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
cName.c_str(), fsCoordName.c_str(),
fsCoordName.c_str(),
- radial2ParamsName.c_str());
+ radial2ParamsName);
// x coord is: -c/b
// y coord is 0.5 (texture is effectively 1D)
@@ -1267,12 +1409,10 @@
StageDesc::kCustomTextureDomain_OptFlagBit) {
GrStringBuilder texDomainName;
tex_domain_name(stageNum, &texDomainName);
- segments->fFSUnis.appendf("uniform %s %s;\n",
- float_vector_type(4),
- texDomainName.c_str());
+ segments->fFSUnis.push_back().set(GrGLShaderVar::kVec4f_Type, texDomainName);
GrStringBuilder coordVar("clampCoord");
segments->fFSCode.appendf("\t%s %s = clamp(%s, %s.xy, %s.zw);\n",
- float_vector_type(coordDims),
+ float_vector_type_str(coordDims),
coordVar.c_str(),
sampleCoords.c_str(),
texDomainName.c_str(),
@@ -1288,17 +1428,17 @@
GrStringBuilder coordVar("tCoord");
coordVar.appendS32(stageNum);
segments->fFSCode.appendf("\t%s %s = %s;\n",
- float_vector_type(coordDims),
- coordVar.c_str(), sampleCoords.c_str());
+ float_vector_type_str(coordDims),
+ coordVar.c_str(), sampleCoords.c_str());
sampleCoords = coordVar;
}
GrAssert(2 == coordDims);
GrStringBuilder accumVar("accum");
accumVar.appendS32(stageNum);
- segments->fFSCode.appendf("\tvec4 %s = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
- segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
- segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
- segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName.c_str(), sampleCoords.c_str(), texelSizeName.c_str(), texelSizeName.c_str(), smear);
+ segments->fFSCode.appendf("\tvec4 %s = %s(%s, %s + vec2(-%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords.c_str(), texelSizeName, texelSizeName, smear);
+ segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,-%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords.c_str(), texelSizeName, texelSizeName, smear);
+ segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(-%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords.c_str(), texelSizeName, texelSizeName, smear);
+ segments->fFSCode.appendf("\t%s += %s(%s, %s + vec2(+%s.x,+%s.y))%s;\n", accumVar.c_str(), texFunc.c_str(), samplerName, sampleCoords.c_str(), texelSizeName, texelSizeName, smear);
segments->fFSCode.appendf("\t%s = .25 * %s%s;\n", fsOutColor, accumVar.c_str(), modulate.c_str());
} else if (ProgramDesc::StageDesc::kConvolution_FetchMode == desc.fFetchMode) {
GrStringBuilder sumVar("sum");
@@ -1315,18 +1455,18 @@
desc.fKernelWidth);
segments->fFSCode.appendf("\t\t%s += %s(%s, %s)%s * %s[i];\n",
sumVar.c_str(), texFunc.c_str(),
- samplerName.c_str(), coordVar.c_str(), smear,
- kernelName.c_str());
+ samplerName, coordVar.c_str(), smear,
+ kernelName);
segments->fFSCode.appendf("\t\t%s += %s;\n",
coordVar.c_str(),
- imageIncrementName.c_str());
+ imageIncrementName);
segments->fFSCode.appendf("\t}\n");
segments->fFSCode.appendf("\t%s = %s%s;\n", fsOutColor,
sumVar.c_str(), modulate.c_str());
} else {
segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n",
fsOutColor, texFunc.c_str(),
- samplerName.c_str(), sampleCoords.c_str(),
+ samplerName, sampleCoords.c_str(),
smear, modulate.c_str());
}
}