aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/GrGLShaderBuilder.cpp
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-30 20:17:31 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-08-30 20:17:31 +0000
commit5a02cb48fdff04dc274d4cb1af8c4dc65a503438 (patch)
treec4c7c3bf5d8d86d0f6274f4abb2d95e281f552ac /src/gpu/gl/GrGLShaderBuilder.cpp
parent74a3a2135ca82ab9324b7e499caa3280348a4fda (diff)
Isolate VertexBuilder from GrGLShaderBuilder
Adds a nested class to GrGLShaderBuilder called VertexBuilder. Now GrGLShaderBuilder can only modify the fragment shader directly. In order to modify the vertex shader, the client code needs to call getVertexShader, which will return null for vertex-less shaders. R=bsalomon@google.com Author: cdalton@nvidia.com Review URL: https://chromiumcodereview.appspot.com/23754003 git-svn-id: http://skia.googlecode.com/svn/trunk@11046 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/gl/GrGLShaderBuilder.cpp')
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp253
1 files changed, 143 insertions, 110 deletions
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index 2554142583..e62bfdebe8 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;