aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLShaderBuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/gl/GrGLShaderBuilder.cpp')
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp166
1 files changed, 98 insertions, 68 deletions
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index b379c78432..c1732b20e7 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -103,7 +103,6 @@ GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo,
, fFSOutputs(kMaxFSOutputs)
, fCtxInfo(ctxInfo)
, fUniformManager(uniformManager)
- , fCurrentStageIdx(kNonStageIdx)
, fFSFeaturesAddedMask(0)
#if GR_GL_EXPERIMENTAL_GS
, fUsesGS(desc.fExperimentalGS)
@@ -215,6 +214,21 @@ void GrGLShaderBuilder::addFSFeature(uint32_t featureBit, const char* extensionN
}
}
+void GrGLShaderBuilder::nameVariable(SkString* out, char prefix, const char* name) {
+ if ('\0' == prefix) {
+ *out = name;
+ } else {
+ out->printf("%c%s", prefix, name);
+ }
+ if (fCodeStage.inStageCode()) {
+ if (out->endsWith('_')) {
+ // Names containing "__" are reserved.
+ out->append("x");
+ }
+ out->appendf("_Stage%d", fCodeStage.stageIndex());
+ }
+}
+
const char* GrGLShaderBuilder::dstColor() {
static const char kFBFetchColorName[] = "gl_LastFragData[0]";
GrGLCaps::FBFetchType fetchType = fCtxInfo.caps()->fbFetchType();
@@ -364,12 +378,7 @@ GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t vi
GrAssert(h2 == h);
uni.fVariable.setType(type);
uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier);
- SkString* uniName = uni.fVariable.accessName();
- if (kNonStageIdx == fCurrentStageIdx) {
- uniName->printf("u%s", name);
- } else {
- uniName->printf("u%s%d", name, fCurrentStageIdx);
- }
+ this->nameVariable(uni.fVariable.accessName(), 'u', name);
uni.fVariable.setArrayCount(count);
uni.fVisibility = visibility;
@@ -415,11 +424,8 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
fVSOutputs.push_back();
fVSOutputs.back().setType(type);
fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
- if (kNonStageIdx == fCurrentStageIdx) {
- fVSOutputs.back().accessName()->printf("v%s", name);
- } else {
- fVSOutputs.back().accessName()->printf("v%s%d", name, fCurrentStageIdx);
- }
+ this->nameVariable(fVSOutputs.back().accessName(), 'v', name);
+
if (vsOutName) {
*vsOutName = fVSOutputs.back().getName().c_str();
}
@@ -436,11 +442,7 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
fGSOutputs.push_back();
fGSOutputs.back().setType(type);
fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier);
- if (kNonStageIdx == fCurrentStageIdx) {
- fGSOutputs.back().accessName()->printf("g%s", name);
- } else {
- fGSOutputs.back().accessName()->printf("g%s%d", name, fCurrentStageIdx);
- }
+ this->nameVariable(fGSOutputs.back().accessName(), 'g', name);
fsName = fGSOutputs.back().accessName();
} else {
fsName = fVSOutputs.back().accessName();
@@ -470,18 +472,16 @@ const char* GrGLShaderBuilder::fragmentPosition() {
} else {
static const char* kCoordName = "fragCoordYDown";
if (!fSetupFragPosition) {
+ // temporarily change the stage index because we're inserting non-stage code.
+ CodeStage::AutoStageRestore csar(&fCodeStage, NULL);
+
GrAssert(GrGLUniformManager::kInvalidUniformHandle == fRTHeightUniform);
const char* rtHeightName;
- // temporarily change the stage index because we're inserting a uniform whose name
- // shouldn't be mangled to be stage-specific.
- int oldStageIdx = fCurrentStageIdx;
- fCurrentStageIdx = kNonStageIdx;
fRTHeightUniform = this->addUniform(kFragment_ShaderType,
kFloat_GrSLType,
"RTHeight",
&rtHeightName);
- fCurrentStageIdx = oldStageIdx;
this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, gl_FragCoord.zw);\n",
kCoordName, rtHeightName);
@@ -514,11 +514,7 @@ void GrGLShaderBuilder::emitFunction(ShaderType shader,
SkString* outName) {
GrAssert(kFragment_ShaderType == shader);
fFSFunctions.append(GrGLSLTypeString(returnType));
- if (kNonStageIdx != fCurrentStageIdx) {
- outName->printf("%s_%d", name, fCurrentStageIdx);
- } else {
- *outName = name;
- }
+ this->nameVariable(outName, '\0', name);
fFSFunctions.appendf(" %s", outName->c_str());
fFSFunctions.append("(");
for (int i = 0; i < argCnt; ++i) {
@@ -623,52 +619,86 @@ void GrGLShaderBuilder::finished(GrGLuint programID) {
fUniformManager.getUniformLocations(programID, fUniforms);
}
-GrGLEffect* GrGLShaderBuilder::createAndEmitGLEffect(
- const GrEffectStage& stage,
- GrGLEffect::EffectKey key,
- const char* fsInColor,
- const char* fsOutColor,
- SkTArray<GrGLUniformManager::UniformHandle, true>* samplerHandles) {
- GrAssert(NULL != stage.getEffect());
-
- const GrEffectRef& effect = *stage.getEffect();
- int numTextures = effect->numTextures();
- SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
- textureSamplers.push_back_n(numTextures);
- for (int i = 0; i < numTextures; ++i) {
- textureSamplers[i].init(this, &effect->textureAccess(i), i);
- samplerHandles->push_back(textureSamplers[i].fSamplerUniform);
- }
- GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords());
-
- int numAttributes = stage.getVertexAttribIndexCount();
- const int* attributeIndices = stage.getVertexAttribIndices();
- SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames;
- for (int i = 0; i < numAttributes; ++i) {
- SkString attributeName("aAttr");
- attributeName.appendS32(attributeIndices[i]);
-
- if (this->addAttribute(effect->vertexAttribType(i), attributeName.c_str())) {
- fEffectAttributes.push_back().set(attributeIndices[i], attributeName);
+void GrGLShaderBuilder::emitEffects(
+ const GrEffectStage* effectStages[],
+ const GrBackendEffectFactory::EffectKey effectKeys[],
+ int effectCnt,
+ SkString* fsInOutColor,
+ GrSLConstantVec* fsInOutColorKnownValue,
+ SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
+ GrGLEffect* glEffects[]) {
+ bool effectEmitted = false;
+
+ SkString inColor = *fsInOutColor;
+ SkString outColor;
+
+ for (int e = 0; e < effectCnt; ++e) {
+ if (NULL == effectStages[e] || GrGLEffect::kNoEffectKey == effectKeys[e]) {
+ continue;
+ }
+
+ GrAssert(NULL != effectStages[e]->getEffect());
+ const GrEffectStage& stage = *effectStages[e];
+ const GrEffectRef& effect = *stage.getEffect();
+
+ CodeStage::AutoStageRestore csar(&fCodeStage, &stage);
+
+ int numTextures = effect->numTextures();
+ SkSTArray<8, GrGLShaderBuilder::TextureSampler> textureSamplers;
+ textureSamplers.push_back_n(numTextures);
+ for (int t = 0; t < numTextures; ++t) {
+ textureSamplers[t].init(this, &effect->textureAccess(t), t);
+ effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUniform);
+ }
+ GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords());
+
+ int numAttributes = stage.getVertexAttribIndexCount();
+ const int* attributeIndices = stage.getVertexAttribIndices();
+ SkSTArray<GrEffect::kMaxVertexAttribs, SkString> attributeNames;
+ for (int a = 0; a < numAttributes; ++a) {
+ // TODO: Make addAttribute mangle the name.
+ SkString attributeName("aAttr");
+ attributeName.appendS32(attributeIndices[a]);
+ if (this->addAttribute(effect->vertexAttribType(a), attributeName.c_str())) {
+ fEffectAttributes.push_back().set(attributeIndices[a], attributeName);
+ }
+ }
+
+ glEffects[e] = effect->getFactory().createGLInstance(drawEffect);
+
+ if (kZeros_GrSLConstantVec == *fsInOutColorKnownValue) {
+ // Effects have no way to communicate zeros, they treat an empty string as ones.
+ this->nameVariable(&inColor, '\0', "input");
+ this->fsCodeAppendf("\tvec4 %s = %s;\n", inColor.c_str(), GrGLSLZerosVecf(4));
}
- }
- GrGLEffect* glEffect = effect->getFactory().createGLInstance(drawEffect);
+ // create var to hold stage result
+ this->nameVariable(&outColor, '\0', "output");
+ this->fsCodeAppendf("\tvec4 %s;\n", outColor.c_str());
- // Enclose custom code in a block to avoid namespace conflicts
- this->fVSCode.appendf("\t{ // %s\n", glEffect->name());
- this->fFSCode.appendf("\t{ // %s \n", glEffect->name());
+ // Enclose custom code in a block to avoid namespace conflicts
+ SkString openBrace;
+ openBrace.printf("\t{ // Stage %d: %s\n", fCodeStage.stageIndex(), glEffects[e]->name());
+ this->fVSCode.append(openBrace);
+ this->fFSCode.append(openBrace);
- glEffect->emitCode(this,
- drawEffect,
- key,
- fsOutColor,
- fsInColor,
- textureSamplers);
- this->fVSCode.appendf("\t}\n");
- this->fFSCode.appendf("\t}\n");
+ glEffects[e]->emitCode(this,
+ drawEffect,
+ effectKeys[e],
+ outColor.c_str(),
+ inColor.isEmpty() ? NULL : inColor.c_str(),
+ textureSamplers);
+ this->fVSCode.append("\t}\n");
+ this->fFSCode.append("\t}\n");
- return glEffect;
+ inColor = outColor;
+ *fsInOutColorKnownValue = kNone_GrSLConstantVec;
+ effectEmitted = true;
+ }
+
+ if (effectEmitted) {
+ *fsInOutColor = outColor;
+ }
}
const SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) const {