Chromium Code Reviews| Index: src/gpu/gl/builders/GrGLProgramBuilder.cpp |
| diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp |
| index 4360f7858d2129171fb19382dfb02bb0e1e64d34..d832450e6e9fef6eba69f3bfb111350361104b8d 100644 |
| --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp |
| +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp |
| @@ -42,7 +42,9 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp |
| GrGLSLExpr4 inputColor; |
| GrGLSLExpr4 inputCoverage; |
| - if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { |
| + if (!pb->emitAndInstallProcs(&inputColor, |
| + &inputCoverage, |
| + gpu->glCaps().maxFragmentTextureUnits())) { |
| return nullptr; |
| } |
| @@ -53,243 +55,17 @@ GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp |
| GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) |
| : INHERITED(args) |
| - , fGeometryProcessor(nullptr) |
| - , fXferProcessor(nullptr) |
| , fGpu(gpu) |
| , fSamplerUniforms(4) |
| , fVaryingHandler(this) |
| , fUniformHandler(this) { |
| } |
| -const GrGLSLCaps* GrGLProgramBuilder::glslCaps() const { |
| - return this->fGpu->ctxInfo().caps()->glslCaps(); |
| -} |
| - |
| -bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) { |
| - // First we loop over all of the installed processors and collect coord transforms. These will |
| - // be sent to the GrGLSLPrimitiveProcessor in its emitCode function |
| - const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); |
| - int totalTextures = primProc.numTextures(); |
| - const int maxTextureUnits = fGpu->glCaps().maxFragmentTextureUnits(); |
| - |
| - for (int i = 0; i < this->pipeline().numFragmentProcessors(); i++) { |
| - const GrFragmentProcessor& processor = this->pipeline().getFragmentProcessor(i); |
| - |
| - if (!primProc.hasTransformedLocalCoords()) { |
| - SkTArray<const GrCoordTransform*, true>& procCoords = fCoordTransforms.push_back(); |
| - processor.gatherCoordTransforms(&procCoords); |
| - } |
| - |
| - totalTextures += processor.numTextures(); |
| - if (totalTextures >= maxTextureUnits) { |
| - GrCapsDebugf(fGpu->caps(), "Program would use too many texture units\n"); |
| - return false; |
| - } |
| - } |
| - |
| - this->emitAndInstallProc(primProc, inputColor, inputCoverage); |
| - |
| - fFragmentProcessors.reset(new GrGLInstalledFragProcs); |
| - int numProcs = this->pipeline().numFragmentProcessors(); |
| - this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentProcessors(), inputColor); |
| - this->emitAndInstallFragProcs(this->pipeline().numColorFragmentProcessors(), numProcs, |
| - inputCoverage); |
| - this->emitAndInstallXferProc(this->pipeline().getXferProcessor(), *inputColor, *inputCoverage, |
| - this->pipeline().ignoresCoverage()); |
| - this->emitFSOutputSwizzle(this->pipeline().getXferProcessor().hasSecondaryOutput()); |
| - return true; |
| -} |
| - |
| -void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, |
| - int numProcs, |
| - GrGLSLExpr4* inOut) { |
| - for (int i = procOffset; i < numProcs; ++i) { |
| - GrGLSLExpr4 output; |
| - const GrFragmentProcessor& fp = this->pipeline().getFragmentProcessor(i); |
| - this->emitAndInstallProc(fp, i, *inOut, &output); |
| - *inOut = output; |
| - } |
| -} |
| - |
| -void GrGLProgramBuilder::nameExpression(GrGLSLExpr4* output, const char* baseName) { |
| - // create var to hold stage result. If we already have a valid output name, just use that |
| - // otherwise create a new mangled one. This name is only valid if we are reordering stages |
| - // and have to tell stage exactly where to put its output. |
| - SkString outName; |
| - if (output->isValid()) { |
| - outName = output->c_str(); |
| - } else { |
| - this->nameVariable(&outName, '\0', baseName); |
| - } |
| - fFS.codeAppendf("vec4 %s;", outName.c_str()); |
| - *output = outName; |
| -} |
| - |
| -// TODO Processors cannot output zeros because an empty string is all 1s |
| -// the fix is to allow effects to take the GrGLSLExpr4 directly |
| -void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentProcessor& fp, |
| - int index, |
| - const GrGLSLExpr4& input, |
| - GrGLSLExpr4* output) { |
| - // Program builders have a bit of state we need to clear with each effect |
| - AutoStageAdvance adv(this); |
| - this->nameExpression(output, "output"); |
| - |
| - // Enclose custom code in a block to avoid namespace conflicts |
| - SkString openBrace; |
| - openBrace.printf("{ // Stage %d, %s\n", fStageIndex, fp.name()); |
| - fFS.codeAppend(openBrace.c_str()); |
| - |
| - this->emitAndInstallProc(fp, index, output->c_str(), input.isOnes() ? nullptr : input.c_str()); |
| - |
| - fFS.codeAppend("}"); |
| +const GrCaps* GrGLProgramBuilder::caps() const { |
| + return fGpu->caps(); |
| } |
| - |
| -void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& proc, |
| - GrGLSLExpr4* outputColor, |
| - GrGLSLExpr4* outputCoverage) { |
| - // Program builders have a bit of state we need to clear with each effect |
| - AutoStageAdvance adv(this); |
| - this->nameExpression(outputColor, "outputColor"); |
| - this->nameExpression(outputCoverage, "outputCoverage"); |
| - |
| - // Enclose custom code in a block to avoid namespace conflicts |
| - SkString openBrace; |
| - openBrace.printf("{ // Stage %d, %s\n", fStageIndex, proc.name()); |
| - fFS.codeAppend(openBrace.c_str()); |
| - fVS.codeAppendf("// Primitive Processor %s\n", proc.name()); |
| - |
| - this->emitAndInstallProc(proc, outputColor->c_str(), outputCoverage->c_str()); |
| - |
| - fFS.codeAppend("}"); |
| -} |
| - |
| -void GrGLProgramBuilder::emitAndInstallProc(const GrFragmentProcessor& fp, |
| - int index, |
| - const char* outColor, |
| - const char* inColor) { |
| - GrGLInstalledFragProc* ifp = new GrGLInstalledFragProc; |
| - |
| - ifp->fGLProc.reset(fp.createGLSLInstance()); |
| - |
| - SkSTArray<4, GrGLSLTextureSampler> samplers(fp.numTextures()); |
| - this->emitSamplers(fp, &samplers, ifp); |
| - |
| - GrGLSLFragmentProcessor::EmitArgs args(&fFS, |
| - &fUniformHandler, |
| - this->glslCaps(), |
| - fp, |
| - outColor, |
| - inColor, |
| - fOutCoords[index], |
| - samplers); |
| - ifp->fGLProc->emitCode(args); |
| - |
| - // We have to check that effects and the code they emit are consistent, ie if an effect |
| - // asks for dst color, then the emit code needs to follow suit |
| - verify(fp); |
| - fFragmentProcessors->fProcs.push_back(ifp); |
| -} |
| - |
| -void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& gp, |
| - const char* outColor, |
| - const char* outCoverage) { |
| - SkASSERT(!fGeometryProcessor); |
| - fGeometryProcessor = new GrGLInstalledGeoProc; |
| - |
| - fGeometryProcessor->fGLProc.reset(gp.createGLSLInstance(*fGpu->glCaps().glslCaps())); |
| - |
| - SkSTArray<4, GrGLSLTextureSampler> samplers(gp.numTextures()); |
| - this->emitSamplers(gp, &samplers, fGeometryProcessor); |
| - |
| - GrGLSLGeometryProcessor::EmitArgs args(&fVS, |
| - &fFS, |
| - &fVaryingHandler, |
| - &fUniformHandler, |
| - this->glslCaps(), |
| - gp, |
| - outColor, |
| - outCoverage, |
| - samplers, |
| - fCoordTransforms, |
| - &fOutCoords); |
| - fGeometryProcessor->fGLProc->emitCode(args); |
| - |
| - // We have to check that effects and the code they emit are consistent, ie if an effect |
| - // asks for dst color, then the emit code needs to follow suit |
| - verify(gp); |
| -} |
| - |
| -void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp, |
| - const GrGLSLExpr4& colorIn, |
| - const GrGLSLExpr4& coverageIn, |
| - bool ignoresCoverage) { |
| - // Program builders have a bit of state we need to clear with each effect |
| - AutoStageAdvance adv(this); |
| - |
| - SkASSERT(!fXferProcessor); |
| - fXferProcessor = new GrGLInstalledXferProc; |
| - |
| - fXferProcessor->fGLProc.reset(xp.createGLSLInstance()); |
| - |
| - // Enable dual source secondary output if we have one |
| - if (xp.hasSecondaryOutput()) { |
| - fFS.enableSecondaryOutput(); |
| - } |
| - |
| - if (this->glslCaps()->mustDeclareFragmentShaderOutput()) { |
| - fFS.enableCustomOutput(); |
| - } |
| - |
| - SkString openBrace; |
| - openBrace.printf("{ // Xfer Processor: %s\n", xp.name()); |
| - fFS.codeAppend(openBrace.c_str()); |
| - |
| - SkSTArray<4, GrGLSLTextureSampler> samplers(xp.numTextures()); |
| - this->emitSamplers(xp, &samplers, fXferProcessor); |
| - |
| - GrGLSLXferProcessor::EmitArgs args(&fFS, |
| - &fUniformHandler, |
| - this->glslCaps(), |
| - xp, colorIn.c_str(), |
| - ignoresCoverage ? nullptr : coverageIn.c_str(), |
| - fFS.getPrimaryColorOutputName(), |
| - fFS.getSecondaryColorOutputName(), |
| - samplers); |
| - fXferProcessor->fGLProc->emitCode(args); |
| - |
| - // We have to check that effects and the code they emit are consistent, ie if an effect |
| - // asks for dst color, then the emit code needs to follow suit |
| - verify(xp); |
| - fFS.codeAppend("}"); |
| -} |
| - |
| -void GrGLProgramBuilder::emitFSOutputSwizzle(bool hasSecondaryOutput) { |
| - // Swizzle the fragment shader outputs if necessary. |
| - GrSwizzle swizzle; |
| - swizzle.setFromKey(this->desc().header().fOutputSwizzle); |
| - if (swizzle != GrSwizzle::RGBA()) { |
| - fFS.codeAppendf("%s = %s.%s;", fFS.getPrimaryColorOutputName(), |
| - fFS.getPrimaryColorOutputName(), |
| - swizzle.c_str()); |
| - if (hasSecondaryOutput) { |
| - fFS.codeAppendf("%s = %s.%s;", fFS.getSecondaryColorOutputName(), |
| - fFS.getSecondaryColorOutputName(), |
| - swizzle.c_str()); |
| - } |
| - } |
| -} |
| - |
| -void GrGLProgramBuilder::verify(const GrPrimitiveProcessor& gp) { |
| - SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); |
| -} |
| - |
| -void GrGLProgramBuilder::verify(const GrXferProcessor& xp) { |
| - SkASSERT(fFS.hasReadDstColor() == xp.willReadDstColor()); |
| -} |
| - |
| -void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) { |
| - SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition()); |
| +const GrGLSLCaps* GrGLProgramBuilder::glslCaps() const { |
|
bsalomon
2016/01/13 17:49:19
\n
egdaniel
2016/01/13 19:59:49
Done.
|
| + return fGpu->ctxInfo().caps()->glslCaps(); |
| } |
| static GrSLType get_sampler_type(const GrTextureAccess& access) { |
| @@ -302,11 +78,8 @@ static GrSLType get_sampler_type(const GrTextureAccess& access) { |
| } |
| } |
| -template <class Proc> |
| void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, |
| - GrGLSLTextureSampler::TextureSamplerArray* outSamplers, |
| - GrGLInstalledProc<Proc>* ip) { |
| - SkDEBUGCODE(ip->fSamplersIdx = fSamplerUniforms.count();) |
| + GrGLSLTextureSampler::TextureSamplerArray* outSamplers) { |
|
bsalomon
2016/01/13 17:49:19
rm two spaces?
egdaniel
2016/01/13 19:59:49
Done.
|
| int numTextures = processor.numTextures(); |
| UniformHandle* localSamplerUniforms = fSamplerUniforms.push_back_n(numTextures); |
| SkString name; |
| @@ -491,15 +264,7 @@ GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { |
| fVaryingHandler.fPathProcVaryingInfos, |
| fGeometryProcessor, |
| fXferProcessor, |
| - fFragmentProcessors.get(), |
| + fFragmentProcessors, |
| &fSamplerUniforms); |
| } |
| -/////////////////////////////////////////////////////////////////////////////////////////////////// |
| - |
| -GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| - int numProcs = fProcs.count(); |
| - for (int i = 0; i < numProcs; ++i) { |
| - delete fProcs[i]; |
| - } |
| -} |