Index: src/gpu/gl/GrGLShaderBuilder.cpp |
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp |
index 2554142583986fda859531fbf73f493bc5e92b3b..e62bfdebe83ae60c74856f4e798012804d6c8a87 100644 |
--- a/src/gpu/gl/GrGLShaderBuilder.cpp |
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp |
@@ -93,37 +93,23 @@ static const char kDstCopyColorName[] = "_dstColor"; |
GrGLShaderBuilder::GrGLShaderBuilder(const GrGLContextInfo& ctxInfo, |
GrGLUniformManager& uniformManager, |
- const GrGLProgramDesc& desc) |
+ const GrGLProgramDesc& desc, |
+ bool needsVertexShader) |
: fUniforms(kVarsPerBlock) |
- , fVSAttrs(kVarsPerBlock) |
- , fVSOutputs(kVarsPerBlock) |
- , fGSInputs(kVarsPerBlock) |
- , fGSOutputs(kVarsPerBlock) |
- , fFSInputs(kVarsPerBlock) |
- , fFSOutputs(kMaxFSOutputs) |
, fCtxInfo(ctxInfo) |
, fUniformManager(uniformManager) |
, fFSFeaturesAddedMask(0) |
-#if GR_GL_EXPERIMENTAL_GS |
- , fUsesGS(SkToBool(desc.getHeader().fExperimentalGS)) |
-#else |
- , fUsesGS(false) |
-#endif |
+ , fFSInputs(kVarsPerBlock) |
+ , fFSOutputs(kMaxFSOutputs) |
, fSetupFragPosition(false) |
, fTopLeftFragPosRead(kTopLeftFragPosRead_FragPosKey == desc.getHeader().fFragPosKey) { |
const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); |
- fPositionVar = &fVSAttrs.push_back(); |
- fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); |
- if (-1 != header.fLocalCoordAttributeIndex) { |
- fLocalCoordsVar = &fVSAttrs.push_back(); |
- fLocalCoordsVar->set(kVec2f_GrSLType, |
- GrGLShaderVar::kAttribute_TypeModifier, |
- "aLocalCoords"); |
- } else { |
- fLocalCoordsVar = fPositionVar; |
+ if (needsVertexShader) { |
+ fVertexBuilder.reset(SkNEW_ARGS(VertexBuilder, (this, desc))); |
} |
+ |
// Emit code to read the dst copy textue if necessary. |
if (kNoDstRead_DstReadKey != header.fDstReadKey && |
GrGLCaps::kNone_FBFetchType == ctxInfo.caps()->fbFetchType()) { |
@@ -375,61 +361,6 @@ GrGLUniformManager::UniformHandle GrGLShaderBuilder::addUniformArray(uint32_t vi |
return h; |
} |
-bool GrGLShaderBuilder::addAttribute(GrSLType type, |
- const char* name) { |
- for (int i = 0; i < fVSAttrs.count(); ++i) { |
- const GrGLShaderVar& attr = fVSAttrs[i]; |
- // if attribute already added, don't add it again |
- if (attr.getName().equals(name)) { |
- SkASSERT(attr.getType() == type); |
- return false; |
- } |
- } |
- fVSAttrs.push_back().set(type, |
- GrGLShaderVar::kAttribute_TypeModifier, |
- name); |
- return true; |
-} |
- |
-void GrGLShaderBuilder::addVarying(GrSLType type, |
- const char* name, |
- const char** vsOutName, |
- const char** fsInName) { |
- fVSOutputs.push_back(); |
- fVSOutputs.back().setType(type); |
- fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); |
- this->nameVariable(fVSOutputs.back().accessName(), 'v', name); |
- |
- if (vsOutName) { |
- *vsOutName = fVSOutputs.back().getName().c_str(); |
- } |
- // input to FS comes either from VS or GS |
- const SkString* fsName; |
- if (fUsesGS) { |
- // if we have a GS take each varying in as an array |
- // and output as non-array. |
- fGSInputs.push_back(); |
- fGSInputs.back().setType(type); |
- fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier); |
- fGSInputs.back().setUnsizedArray(); |
- *fGSInputs.back().accessName() = fVSOutputs.back().getName(); |
- fGSOutputs.push_back(); |
- fGSOutputs.back().setType(type); |
- fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); |
- this->nameVariable(fGSOutputs.back().accessName(), 'g', name); |
- fsName = fGSOutputs.back().accessName(); |
- } else { |
- fsName = fVSOutputs.back().accessName(); |
- } |
- fFSInputs.push_back(); |
- fFSInputs.back().setType(type); |
- fFSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier); |
- fFSInputs.back().setName(*fsName); |
- if (fsInName) { |
- *fsInName = fsName->c_str(); |
- } |
-} |
- |
const char* GrGLShaderBuilder::fragmentPosition() { |
if (fCodeStage.inStageCode()) { |
const GrEffectRef& effect = *fCodeStage.effectStage()->getEffect(); |
@@ -547,31 +478,6 @@ void GrGLShaderBuilder::appendUniformDecls(ShaderVisibility visibility, |
} |
} |
-void GrGLShaderBuilder::vsGetShader(SkString* shaderStr) const { |
- *shaderStr = GrGetGLSLVersionDecl(fCtxInfo); |
- this->appendUniformDecls(kVertex_Visibility, shaderStr); |
- this->appendDecls(fVSAttrs, shaderStr); |
- this->appendDecls(fVSOutputs, shaderStr); |
- shaderStr->append("void main() {\n"); |
- shaderStr->append(fVSCode); |
- shaderStr->append("}\n"); |
-} |
- |
-void GrGLShaderBuilder::gsGetShader(SkString* shaderStr) const { |
- if (!fUsesGS) { |
- shaderStr->reset(); |
- return; |
- } |
- |
- *shaderStr = GrGetGLSLVersionDecl(fCtxInfo); |
- shaderStr->append(fGSHeader); |
- this->appendDecls(fGSInputs, shaderStr); |
- this->appendDecls(fGSOutputs, shaderStr); |
- shaderStr->append("void main() {\n"); |
- shaderStr->append(fGSCode); |
- shaderStr->append("}\n"); |
-} |
- |
void GrGLShaderBuilder::fsGetShader(SkString* shaderStr) const { |
*shaderStr = GrGetGLSLVersionDecl(fCtxInfo); |
shaderStr->append(fFSExtensions); |
@@ -620,18 +526,20 @@ void GrGLShaderBuilder::emitEffects( |
textureSamplers[t].init(this, &effect->textureAccess(t), t); |
effectSamplerHandles[e]->push_back(textureSamplers[t].fSamplerUniform); |
} |
- GrDrawEffect drawEffect(stage, this->hasExplicitLocalCoords()); |
+ GrDrawEffect drawEffect(stage, fVertexBuilder.get() |
+ && fVertexBuilder->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. |
+ SkASSERT(fVertexBuilder.get()); |
SkString attributeName("aAttr"); |
attributeName.appendS32(attributeIndices[a]); |
- if (this->addAttribute(effect->vertexAttribType(a), attributeName.c_str())) { |
- fEffectAttributes.push_back().set(attributeIndices[a], attributeName); |
- } |
+ fVertexBuilder->addEffectAttribute(attributeIndices[a], |
+ effect->vertexAttribType(a), |
+ attributeName); |
} |
glEffects[e] = effect->getFactory().createGLInstance(drawEffect); |
@@ -649,8 +557,10 @@ void GrGLShaderBuilder::emitEffects( |
// 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); |
+ if (fVertexBuilder.get()) { |
+ fVertexBuilder->vsCodeAppend(openBrace.c_str()); |
+ } |
+ this->fsCodeAppend(openBrace.c_str()); |
glEffects[e]->emitCode(this, |
drawEffect, |
@@ -658,8 +568,11 @@ void GrGLShaderBuilder::emitEffects( |
outColor.c_str(), |
inColor.isEmpty() ? NULL : inColor.c_str(), |
textureSamplers); |
- this->fVSCode.append("\t}\n"); |
- this->fFSCode.append("\t}\n"); |
+ |
+ if (fVertexBuilder.get()) { |
+ fVertexBuilder->vsCodeAppend("\t}\n"); |
+ } |
+ this->fsCodeAppend("\t}\n"); |
inColor = outColor; |
*fsInOutColorKnownValue = kNone_GrSLConstantVec; |
@@ -671,7 +584,127 @@ void GrGLShaderBuilder::emitEffects( |
} |
} |
-const SkString* GrGLShaderBuilder::getEffectAttributeName(int attributeIndex) const { |
+//////////////////////////////////////////////////////////////////////////// |
+ |
+GrGLShaderBuilder::VertexBuilder::VertexBuilder(GrGLShaderBuilder* parent, |
+ const GrGLProgramDesc& desc) |
+ : fVSAttrs(kVarsPerBlock) |
+ , fVSOutputs(kVarsPerBlock) |
+ , fGSInputs(kVarsPerBlock) |
+ , fGSOutputs(kVarsPerBlock) |
+ , fParent(parent) |
+#if GR_GL_EXPERIMENTAL_GS |
+ , fUsesGS(SkToBool(desc.getHeader().fExperimentalGS)) |
+#else |
+ , fUsesGS(false) |
+#endif |
+{ |
+ const GrGLProgramDesc::KeyHeader& header = desc.getHeader(); |
+ |
+ fPositionVar = &fVSAttrs.push_back(); |
+ fPositionVar->set(kVec2f_GrSLType, GrGLShaderVar::kAttribute_TypeModifier, "aPosition"); |
+ if (-1 != header.fLocalCoordAttributeIndex) { |
+ fLocalCoordsVar = &fVSAttrs.push_back(); |
+ fLocalCoordsVar->set(kVec2f_GrSLType, |
+ GrGLShaderVar::kAttribute_TypeModifier, |
+ "aLocalCoords"); |
+ } else { |
+ fLocalCoordsVar = fPositionVar; |
+ } |
+} |
+ |
+bool GrGLShaderBuilder::VertexBuilder::addAttribute(GrSLType type, |
+ const char* name) { |
+ for (int i = 0; i < fVSAttrs.count(); ++i) { |
+ const GrGLShaderVar& attr = fVSAttrs[i]; |
+ // if attribute already added, don't add it again |
+ if (attr.getName().equals(name)) { |
+ SkASSERT(attr.getType() == type); |
+ return false; |
+ } |
+ } |
+ fVSAttrs.push_back().set(type, |
+ GrGLShaderVar::kAttribute_TypeModifier, |
+ name); |
+ return true; |
+} |
+ |
+bool GrGLShaderBuilder::VertexBuilder::addEffectAttribute(int attributeIndex, |
+ GrSLType type, |
+ const SkString& name) { |
+ if (!this->addAttribute(type, name.c_str())) { |
+ return false; |
+ } |
+ |
+ fEffectAttributes.push_back().set(attributeIndex, name); |
+ return true; |
+} |
+ |
+void GrGLShaderBuilder::VertexBuilder::addVarying(GrSLType type, |
+ const char* name, |
+ const char** vsOutName, |
+ const char** fsInName) { |
+ fVSOutputs.push_back(); |
+ fVSOutputs.back().setType(type); |
+ fVSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); |
+ fParent->nameVariable(fVSOutputs.back().accessName(), 'v', name); |
+ |
+ if (vsOutName) { |
+ *vsOutName = fVSOutputs.back().getName().c_str(); |
+ } |
+ // input to FS comes either from VS or GS |
+ const SkString* fsName; |
+ if (fUsesGS) { |
+ // if we have a GS take each varying in as an array |
+ // and output as non-array. |
+ fGSInputs.push_back(); |
+ fGSInputs.back().setType(type); |
+ fGSInputs.back().setTypeModifier(GrGLShaderVar::kVaryingIn_TypeModifier); |
+ fGSInputs.back().setUnsizedArray(); |
+ *fGSInputs.back().accessName() = fVSOutputs.back().getName(); |
+ fGSOutputs.push_back(); |
+ fGSOutputs.back().setType(type); |
+ fGSOutputs.back().setTypeModifier(GrGLShaderVar::kVaryingOut_TypeModifier); |
+ fParent->nameVariable(fGSOutputs.back().accessName(), 'g', name); |
+ fsName = fGSOutputs.back().accessName(); |
+ } else { |
+ fsName = fVSOutputs.back().accessName(); |
+ } |
+ fParent->fsInputAppend().set(type, |
+ GrGLShaderVar::kVaryingIn_TypeModifier, |
+ *fsName); |
+ if (fsInName) { |
+ *fsInName = fsName->c_str(); |
+ } |
+} |
+ |
+void GrGLShaderBuilder::VertexBuilder::vsGetShader(SkString* shaderStr) const { |
+ *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo()); |
+ fParent->appendUniformDecls(kVertex_Visibility, shaderStr); |
+ fParent->appendDecls(fVSAttrs, shaderStr); |
+ fParent->appendDecls(fVSOutputs, shaderStr); |
+ shaderStr->append("void main() {\n"); |
+ shaderStr->append(fVSCode); |
+ shaderStr->append("}\n"); |
+} |
+ |
+void GrGLShaderBuilder::VertexBuilder::gsGetShader(SkString* shaderStr) const { |
+ if (!fUsesGS) { |
+ shaderStr->reset(); |
+ return; |
+ } |
+ |
+ *shaderStr = GrGetGLSLVersionDecl(fParent->ctxInfo()); |
+ shaderStr->append(fGSHeader); |
+ fParent->appendDecls(fGSInputs, shaderStr); |
+ fParent->appendDecls(fGSOutputs, shaderStr); |
+ shaderStr->append("void main() {\n"); |
+ shaderStr->append(fGSCode); |
+ shaderStr->append("}\n"); |
+} |
+ |
+ |
+const SkString* GrGLShaderBuilder::VertexBuilder::getEffectAttributeName(int attributeIndex) const { |
const AttributePair* attribEnd = this->getEffectAttributes().end(); |
for (const AttributePair* attrib = this->getEffectAttributes().begin(); |
attrib != attribEnd; |