Add method to GrGLShadeVar to create GLSL string accessing an element

of an array.
codereview.appspot.com/5437149/



git-svn-id: http://skia.googlecode.com/svn/trunk@2818 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
tomhudson@google.com 2011-12-07 15:06:29 +00:00
parent 59ccef695c
commit da668988e9
2 changed files with 111 additions and 53 deletions

View File

@ -1324,7 +1324,7 @@ bool isRadialMapping(GrGLProgram::StageDesc::CoordMapping mapping) {
GrGLProgram::StageDesc::kRadial2GradientDegenerate_CoordMapping == mapping);
}
const char* genRadialVS(int stageNum,
GrGLShaderVar* genRadialVS(int stageNum,
ShaderCodeSegments* segments,
GrGLProgram::StageUniLocations* locations,
const char** radial2VaryingVSName,
@ -1351,20 +1351,25 @@ const char* genRadialVS(int stageNum,
radial2VaryingVSName,
radial2VaryingFSName);
GrStringBuilder radial2p2;
GrStringBuilder radial2p3;
radial2FSParams->appendArrayAccess(2, &radial2p2);
radial2FSParams->appendArrayAccess(3, &radial2p3);
// r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3])
const char* r2ParamName = radial2FSParams->getName().c_str();
segments->fVSCode.appendf("\t%s = 2.0 *(%s[2] * %s.x - %s[3]);\n",
*radial2VaryingVSName, r2ParamName,
varyingVSName, r2ParamName);
segments->fVSCode.appendf("\t%s = 2.0 *(%s * %s.x - %s);\n",
*radial2VaryingVSName, radial2p2.c_str(),
varyingVSName, radial2p3.c_str());
}
return radial2FSParams->getName().c_str();
return radial2FSParams;
}
bool genRadial2GradientCoordMapping(int stageNum,
ShaderCodeSegments* segments,
const char* radial2VaryingFSName,
const char* radial2ParamsName,
GrGLShaderVar* radial2Params,
GrStringBuilder& sampleCoords,
GrStringBuilder& fsCoordName,
int varyingDims,
@ -1377,6 +1382,19 @@ bool genRadial2GradientCoordMapping(int stageNum,
ac4Name.appendS32(stageNum);
rootName.appendS32(stageNum);
GrStringBuilder radial2p0;
GrStringBuilder radial2p1;
GrStringBuilder radial2p2;
GrStringBuilder radial2p3;
GrStringBuilder radial2p4;
GrStringBuilder radial2p5;
radial2Params->appendArrayAccess(0, &radial2p0);
radial2Params->appendArrayAccess(1, &radial2p1);
radial2Params->appendArrayAccess(2, &radial2p2);
radial2Params->appendArrayAccess(3, &radial2p3);
radial2Params->appendArrayAccess(4, &radial2p4);
radial2Params->appendArrayAccess(5, &radial2p5);
// if we were able to interpolate the linear component bVar is the varying
// otherwise compute it
GrStringBuilder bVar;
@ -1387,19 +1405,19 @@ bool genRadial2GradientCoordMapping(int stageNum,
GrAssert(3 == varyingDims);
bVar = "b";
bVar.appendS32(stageNum);
segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
bVar.c_str(), radial2ParamsName,
fsCoordName.c_str(), radial2ParamsName);
segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
bVar.c_str(), radial2p2.c_str(),
fsCoordName.c_str(), radial2p3.c_str());
}
// c = (x^2)+(y^2) - params[4]
segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s;\n",
cName.c_str(), fsCoordName.c_str(),
fsCoordName.c_str(),
radial2ParamsName);
radial2p4.c_str());
// ac4 = 4.0 * params[0] * c
segments->fFSCode.appendf("\tfloat %s = %s[0] * 4.0 * %s;\n",
ac4Name.c_str(), radial2ParamsName,
segments->fFSCode.appendf("\tfloat %s = %s * 4.0 * %s;\n",
ac4Name.c_str(), radial2p0.c_str(),
cName.c_str());
// root = sqrt(b^2-4ac)
@ -1410,16 +1428,16 @@ bool genRadial2GradientCoordMapping(int stageNum,
// 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,
rootName.c_str(), radial2ParamsName);
sampleCoords.printf("vec2((-%s + %s * %s) * %s, 0.5)",
bVar.c_str(), radial2p5.c_str(),
rootName.c_str(), radial2p1.c_str());
return true;
}
bool genRadial2GradientDegenerateCoordMapping(int stageNum,
ShaderCodeSegments* segments,
const char* radial2VaryingFSName,
const char* radial2ParamsName,
GrGLShaderVar* radial2Params,
GrStringBuilder& sampleCoords,
GrStringBuilder& fsCoordName,
int varyingDims,
@ -1428,6 +1446,13 @@ bool genRadial2GradientDegenerateCoordMapping(int stageNum,
cName.appendS32(stageNum);
GrStringBuilder radial2p2;
GrStringBuilder radial2p3;
GrStringBuilder radial2p4;
radial2Params->appendArrayAccess(2, &radial2p2);
radial2Params->appendArrayAccess(3, &radial2p3);
radial2Params->appendArrayAccess(4, &radial2p4);
// if we were able to interpolate the linear component bVar is the varying
// otherwise compute it
GrStringBuilder bVar;
@ -1438,16 +1463,16 @@ bool genRadial2GradientDegenerateCoordMapping(int stageNum,
GrAssert(3 == varyingDims);
bVar = "b";
bVar.appendS32(stageNum);
segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s[2] * %s.x - %s[3]);\n",
bVar.c_str(), radial2ParamsName,
fsCoordName.c_str(), radial2ParamsName);
segments->fFSCode.appendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n",
bVar.c_str(), radial2p2.c_str(),
fsCoordName.c_str(), radial2p3.c_str());
}
// c = (x^2)+(y^2) - params[4]
segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s[4];\n",
segments->fFSCode.appendf("\tfloat %s = dot(%s, %s) - %s;\n",
cName.c_str(), fsCoordName.c_str(),
fsCoordName.c_str(),
radial2ParamsName);
radial2p4.c_str());
// x coord is: -c/b
// y coord is 0.5 (texture is effectively 1D)
@ -1492,19 +1517,19 @@ void genConvolutionVS(int stageNum,
const StageDesc& desc,
ShaderCodeSegments* segments,
GrGLProgram::StageUniLocations* locations,
const char** kernelName,
GrGLShaderVar** kernel,
const char** imageIncrementName,
const char* varyingVSName) {
GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
kernel->setType(GrGLShaderVar::kFloat_Type);
kernel->setArrayCount(desc.fKernelWidth);
//GrGLShaderVar* kernel = &segments->fFSUnis.push_back();
*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(),
(*kernel)->accessName(),
imgInc->accessName());
*kernelName = kernel->getName().c_str();
*imageIncrementName = imgInc->getName().c_str();
// need image increment in both VS and FS
@ -1522,7 +1547,7 @@ void genConvolutionFS(int stageNum,
const StageDesc& desc,
ShaderCodeSegments* segments,
const char* samplerName,
const char* kernelName,
GrGLShaderVar* kernel,
const char* swizzle,
const char* imageIncrementName,
const char* fsOutColor,
@ -1534,6 +1559,9 @@ void genConvolutionFS(int stageNum,
GrStringBuilder coordVar("coord");
coordVar.appendS32(stageNum);
GrStringBuilder kernelIndex;
kernel->appendArrayAccess("i", &kernelIndex);
segments->fFSCode.appendf("\tvec4 %s = vec4(0, 0, 0, 0);\n",
sumVar.c_str());
segments->fFSCode.appendf("\tvec2 %s = %s;\n",
@ -1541,10 +1569,10 @@ void genConvolutionFS(int stageNum,
sampleCoords.c_str());
segments->fFSCode.appendf("\tfor (int i = 0; i < %d; i++) {\n",
desc.fKernelWidth);
segments->fFSCode.appendf("\t\t%s += %s(%s, %s)%s * %s[i];\n",
segments->fFSCode.appendf("\t\t%s += %s(%s, %s)%s * %s;\n",
sumVar.c_str(), texFunc.c_str(),
samplerName, coordVar.c_str(), swizzle,
kernelName);
kernelIndex.c_str());
segments->fFSCode.appendf("\t\t%s += %s;\n",
coordVar.c_str(),
imageIncrementName);
@ -1630,24 +1658,24 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
vector_all_coords(varyingDims));
}
const char* radial2ParamsName = NULL;
const char *radial2VaryingVSName = NULL;
const char *radial2VaryingFSName = NULL;
GrGLShaderVar* radial2Params = NULL;
const char* radial2VaryingVSName = NULL;
const char* radial2VaryingFSName = NULL;
if (isRadialMapping((StageDesc::CoordMapping) desc.fCoordMapping)) {
radial2ParamsName = genRadialVS(stageNum, segments,
locations,
&radial2VaryingVSName,
&radial2VaryingFSName,
varyingVSName,
varyingDims, coordDims);
radial2Params = genRadialVS(stageNum, segments,
locations,
&radial2VaryingVSName,
&radial2VaryingFSName,
varyingVSName,
varyingDims, coordDims);
}
const char* kernelName = NULL;
GrGLShaderVar* kernel = NULL;
const char* imageIncrementName = NULL;
if (StageDesc::kConvolution_FetchMode == desc.fFetchMode) {
genConvolutionVS(stageNum, desc, segments, locations,
&kernelName, &imageIncrementName, varyingVSName);
&kernel, &imageIncrementName, varyingVSName);
}
/// Fragment Shader Stuff
@ -1696,7 +1724,7 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
case StageDesc::kRadial2Gradient_CoordMapping:
complexCoord = genRadial2GradientCoordMapping(
stageNum, segments,
radial2VaryingFSName, radial2ParamsName,
radial2VaryingFSName, radial2Params,
sampleCoords, fsCoordName,
varyingDims, coordDims);
@ -1704,7 +1732,7 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
case StageDesc::kRadial2GradientDegenerate_CoordMapping:
complexCoord = genRadial2GradientDegenerateCoordMapping(
stageNum, segments,
radial2VaryingFSName, radial2ParamsName,
radial2VaryingFSName, radial2Params,
sampleCoords, fsCoordName,
varyingDims, coordDims);
break;
@ -1754,7 +1782,7 @@ void GrGLProgram::genStageCode(const GrGLInterface* gl,
GrAssert(!(desc.fInConfigFlags &
StageDesc::kMulRGBByAlpha_InConfigFlag));
genConvolutionFS(stageNum, desc, segments,
samplerName, kernelName, swizzle, imageIncrementName, fsOutColor,
samplerName, kernel, swizzle, imageIncrementName, fsOutColor,
sampleCoords, texFunc, modulate);
break;
default:

View File

@ -12,6 +12,8 @@
#include "GrGLInterface.h"
#include "GrStringBuilder.h"
#define USE_UNIFORM_FLOAT_ARRAYS true
/**
* Represents a variable in a shader
*/
@ -34,13 +36,15 @@ public:
fType = kFloat_Type;
fCount = kNonArray;
fEmitPrecision = false;
fUseUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS;
}
GrGLShaderVar(const GrGLShaderVar& var)
: fType(var.fType)
, fName(var.fName)
, fCount(var.fCount)
, fEmitPrecision(var.fEmitPrecision) {}
, fEmitPrecision(var.fEmitPrecision)
, fUseUniformFloatArrays(var.fUseUniformFloatArrays) {}
/**
* Values for array count that have special meaning. We allow 1-sized arrays.
@ -55,11 +59,13 @@ public:
*/
void set(Type type,
const GrStringBuilder& name,
bool emitPrecision = false) {
bool emitPrecision = false,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fName = name;
fCount = kNonArray;
fEmitPrecision = emitPrecision;
fUseUniformFloatArrays = useUniformFloatArrays;
}
/**
@ -67,11 +73,13 @@ public:
*/
void set(Type type,
const char* name,
bool specifyPrecision = false) {
bool specifyPrecision = false,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fName = name;
fCount = kNonArray;
fEmitPrecision = specifyPrecision;
fUseUniformFloatArrays = useUniformFloatArrays;
}
/**
@ -80,11 +88,13 @@ public:
void set(Type type,
const GrStringBuilder& name,
int count,
bool specifyPrecision = false) {
bool specifyPrecision = false,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fName = name;
fCount = count;
fEmitPrecision = specifyPrecision;
fUseUniformFloatArrays = useUniformFloatArrays;
}
/**
@ -93,11 +103,13 @@ public:
void set(Type type,
const char* name,
int count,
bool specifyPrecision = false) {
bool specifyPrecision = false,
bool useUniformFloatArrays = USE_UNIFORM_FLOAT_ARRAYS) {
fType = type;
fName = name;
fCount = count;
fEmitPrecision = specifyPrecision;
fUseUniformFloatArrays = useUniformFloatArrays;
}
/**
@ -165,21 +177,22 @@ public:
out->append(PrecisionString(gl));
out->append(" ");
}
Type effectiveType = this->getType();
if (this->isArray()) {
if (this->isUnsizedArray()) {
out->appendf("%s %s[]",
TypeString(this->getType()),
TypeString(effectiveType),
this->getName().c_str());
} else {
GrAssert(this->getArrayCount() > 0);
out->appendf("%s %s[%d]",
TypeString(this->getType()),
TypeString(effectiveType),
this->getName().c_str(),
this->getArrayCount());
}
} else {
out->appendf("%s %s",
TypeString(this->getType()),
TypeString(effectiveType),
this->getName().c_str());
}
}
@ -204,6 +217,20 @@ public:
}
}
void appendArrayAccess(int index, GrStringBuilder* out) {
out->appendf("%s[%d]%s",
this->getName().c_str(),
index,
fUseUniformFloatArrays ? "" : ".x");
}
void appendArrayAccess(const char* indexName, GrStringBuilder* out) {
out->appendf("%s[%s]%s",
this->getName().c_str(),
indexName,
fUseUniformFloatArrays ? "" : ".x");
}
private:
static const char* PrecisionString(const GrGLInterface* gl) {
return gl->supportsDesktop() ? "" : "mediump";
@ -213,6 +240,9 @@ private:
GrStringBuilder fName;
int fCount;
bool fEmitPrecision;
/// Work around driver bugs on some hardware that don't correctly
/// support uniform float []
bool fUseUniformFloatArrays;
};
#endif