diff options
Diffstat (limited to 'src/gpu/gl/GrGLShaderBuilder.cpp')
-rw-r--r-- | src/gpu/gl/GrGLShaderBuilder.cpp | 166 |
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 { |