Index: src/gpu/gl/builders/GrGLProgramBuilder.cpp |
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp |
index 8b1843c6cb52fb1d16851775b1dd73f7dd53905e..166ba0c5a4358f32a5fa022b37e3a8cf4cf9a141 100644 |
--- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp |
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp |
@@ -9,7 +9,6 @@ |
#include "GrAutoLocaleSetter.h" |
#include "GrCoordTransform.h" |
-#include "GrGLPathProgramBuilder.h" |
#include "GrGLProgramBuilder.h" |
#include "GrTexture.h" |
#include "SkRTConf.h" |
@@ -32,7 +31,7 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp |
// create a builder. This will be handed off to effects so they can use it to add |
// uniforms, varyings, textures, etc |
- SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(args, gpu)); |
+ SkAutoTDelete<GrGLProgramBuilder> builder(new GrGLProgramBuilder(gpu, args)); |
GrGLProgramBuilder* pb = builder.get(); |
@@ -48,18 +47,6 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp |
return pb->finalize(); |
} |
-GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& args, |
- GrGLGpu* gpu) { |
- if (args.fPrimitiveProcessor->isPathRendering()) { |
- SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && |
- !args.fPrimitiveProcessor->willUseGeoShader() && |
- args.fPrimitiveProcessor->numAttribs() == 0); |
- return new GrGLPathProgramBuilder(gpu, args); |
- } else { |
- return new GrGLProgramBuilder(gpu, args); |
- } |
-} |
- |
///////////////////////////////////////////////////////////////////////////// |
GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) |
@@ -73,7 +60,8 @@ GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) |
, fArgs(args) |
, fGpu(gpu) |
, fUniforms(kVarsPerBlock) |
- , fSamplerUniforms(4) { |
+ , fSamplerUniforms(4) |
+ , fSeparableVaryingInfos(kVarsPerBlock) { |
} |
void GrGLProgramBuilder::addVarying(const char* name, |
@@ -100,16 +88,20 @@ void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att |
fFS.codeAppendf("%s = %s;", output, v.fsIn()); |
} |
-GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVarying(const char*, |
- GrGLVertToFrag*, |
- GrSLPrecision) { |
- // This call is not used for non-NVPR backends. However, the polymorphism between |
- // GrPrimitiveProcessor, GrGLPrimitiveProcessor and GrGLProgramBuilder does not allow for |
- // a system where GrGLPathProcessor would be able to refer to a primitive-specific builder |
- // that would understand separable varyings. Thus separable varyings need to be present |
- // early in the inheritance chain of builders. |
- SkASSERT(false); |
- return SeparableVaryingHandle(); |
+GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVarying( |
+ const char* name, |
+ GrGLVertToFrag* v, |
+ GrSLPrecision fsPrecision) { |
+ // This call is not used for non-NVPR backends. |
+ SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport() && |
+ fArgs.fPrimitiveProcessor->isPathRendering() && |
+ !fArgs.fPrimitiveProcessor->willUseGeoShader() && |
+ fArgs.fPrimitiveProcessor->numAttribs() == 0); |
+ this->addVarying(name, v, fsPrecision); |
+ SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back(); |
+ varyingInfo.fVariable = this->getFragmentShaderBuilder()->fInputs.back(); |
+ varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1; |
+ return SeparableVaryingHandle(varyingInfo.fLocation); |
} |
void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* name) { |
@@ -440,6 +432,19 @@ void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { |
} |
fFS.bindFragmentShaderLocations(programID); |
+ |
+ // handle NVPR separable varyings |
+ if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() || |
+ !fGpu->glPathRendering()->shouldBindFragmentInputs()) { |
+ return; |
+ } |
+ int count = fSeparableVaryingInfos.count(); |
+ for (int i = 0; i < count; ++i) { |
+ GL_CALL(BindFragmentInputLocation(programID, |
+ i, |
+ fSeparableVaryingInfos[i].fVariable.c_str())); |
+ fSeparableVaryingInfos[i].fLocation = i; |
+ } |
} |
bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) { |
@@ -476,6 +481,21 @@ void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { |
fUniforms[i].fLocation = location; |
} |
} |
+ |
+ // handle NVPR separable varyings |
+ if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() || |
+ !fGpu->glPathRendering()->shouldBindFragmentInputs()) { |
+ return; |
+ } |
+ int count = fSeparableVaryingInfos.count(); |
+ for (int i = 0; i < count; ++i) { |
+ GrGLint location; |
+ GL_CALL_RET(location, |
+ GetProgramResourceLocation(programID, |
+ GR_GL_FRAGMENT_INPUT, |
+ fSeparableVaryingInfos[i].fVariable.c_str())); |
+ fSeparableVaryingInfos[i].fLocation = location; |
+ } |
} |
void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs) { |
@@ -490,6 +510,7 @@ void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { |
GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { |
return new GrGLProgram(fGpu, this->desc(), fUniformHandles, programID, fUniforms, |
+ fSeparableVaryingInfos, |
fGeometryProcessor, fXferProcessor, fFragmentProcessors.get(), |
&fSamplerUniforms); |
} |