| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrGLProgramBuilder.h" | 8 #include "GrGLProgramBuilder.h" |
| 9 | 9 |
| 10 #include "gl/GrGLGeometryProcessor.h" | 10 #include "gl/GrGLGeometryProcessor.h" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 | 48 |
| 49 return pb->finalize(); | 49 return pb->finalize(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg
s, | 52 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg
s, |
| 53 GrGLGpu* gpu) { | 53 GrGLGpu* gpu) { |
| 54 if (args.fPrimitiveProcessor->isPathRendering()) { | 54 if (args.fPrimitiveProcessor->isPathRendering()) { |
| 55 SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && | 55 SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && |
| 56 !args.fPrimitiveProcessor->willUseGeoShader() && | 56 !args.fPrimitiveProcessor->willUseGeoShader() && |
| 57 args.fPrimitiveProcessor->numAttribs() == 0); | 57 args.fPrimitiveProcessor->numAttribs() == 0); |
| 58 return SkNEW_ARGS(GrGLPathProgramBuilder, (gpu, args)); | 58 return new GrGLPathProgramBuilder(gpu, args); |
| 59 } else { | 59 } else { |
| 60 return SkNEW_ARGS(GrGLProgramBuilder, (gpu, args)); | 60 return new GrGLProgramBuilder(gpu, args); |
| 61 } | 61 } |
| 62 } | 62 } |
| 63 | 63 |
| 64 ///////////////////////////////////////////////////////////////////////////// | 64 ///////////////////////////////////////////////////////////////////////////// |
| 65 | 65 |
| 66 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) | 66 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) |
| 67 : fVS(this) | 67 : fVS(this) |
| 68 , fGS(this) | 68 , fGS(this) |
| 69 , fFS(this, args.fDesc->header().fFragPosKey) | 69 , fFS(this, args.fDesc->header().fFragPosKey) |
| 70 , fOutOfStage(true) | 70 , fOutOfStage(true) |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 | 196 |
| 197 totalTextures += processor->numTextures(); | 197 totalTextures += processor->numTextures(); |
| 198 if (totalTextures >= maxTextureUnits) { | 198 if (totalTextures >= maxTextureUnits) { |
| 199 GrCapsDebugf(fGpu->caps(), "Program would use too many texture units
\n"); | 199 GrCapsDebugf(fGpu->caps(), "Program would use too many texture units
\n"); |
| 200 return false; | 200 return false; |
| 201 } | 201 } |
| 202 } | 202 } |
| 203 | 203 |
| 204 this->emitAndInstallProc(primProc, inputColor, inputCoverage); | 204 this->emitAndInstallProc(primProc, inputColor, inputCoverage); |
| 205 | 205 |
| 206 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); | 206 fFragmentProcessors.reset(new GrGLInstalledFragProcs); |
| 207 int numProcs = this->pipeline().numFragmentStages(); | 207 int numProcs = this->pipeline().numFragmentStages(); |
| 208 this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentStages(),
inputColor); | 208 this->emitAndInstallFragProcs(0, this->pipeline().numColorFragmentStages(),
inputColor); |
| 209 this->emitAndInstallFragProcs(this->pipeline().numColorFragmentStages(), num
Procs, | 209 this->emitAndInstallFragProcs(this->pipeline().numColorFragmentStages(), num
Procs, |
| 210 inputCoverage); | 210 inputCoverage); |
| 211 this->emitAndInstallXferProc(*this->pipeline().getXferProcessor(), *inputCol
or, *inputCoverage); | 211 this->emitAndInstallXferProc(*this->pipeline().getXferProcessor(), *inputCol
or, *inputCoverage); |
| 212 return true; | 212 return true; |
| 213 } | 213 } |
| 214 | 214 |
| 215 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, | 215 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, |
| 216 int numProcs, | 216 int numProcs, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 273 |
| 274 this->emitAndInstallProc(proc, outputColor->c_str(), outputCoverage->c_str()
); | 274 this->emitAndInstallProc(proc, outputColor->c_str(), outputCoverage->c_str()
); |
| 275 | 275 |
| 276 fFS.codeAppend("}"); | 276 fFS.codeAppend("}"); |
| 277 } | 277 } |
| 278 | 278 |
| 279 void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs, | 279 void GrGLProgramBuilder::emitAndInstallProc(const GrPendingFragmentStage& fs, |
| 280 int index, | 280 int index, |
| 281 const char* outColor, | 281 const char* outColor, |
| 282 const char* inColor) { | 282 const char* inColor) { |
| 283 GrGLInstalledFragProc* ifp = SkNEW(GrGLInstalledFragProc); | 283 GrGLInstalledFragProc* ifp = new GrGLInstalledFragProc; |
| 284 | 284 |
| 285 const GrFragmentProcessor& fp = *fs.processor(); | 285 const GrFragmentProcessor& fp = *fs.processor(); |
| 286 ifp->fGLProc.reset(fp.createGLInstance()); | 286 ifp->fGLProc.reset(fp.createGLInstance()); |
| 287 | 287 |
| 288 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures()); | 288 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(fp.numTextures()); |
| 289 this->emitSamplers(fp, &samplers, ifp); | 289 this->emitSamplers(fp, &samplers, ifp); |
| 290 | 290 |
| 291 GrGLFragmentProcessor::EmitArgs args(this, fp, outColor, inColor, fOutCoords
[index], samplers); | 291 GrGLFragmentProcessor::EmitArgs args(this, fp, outColor, inColor, fOutCoords
[index], samplers); |
| 292 ifp->fGLProc->emitCode(args); | 292 ifp->fGLProc->emitCode(args); |
| 293 | 293 |
| 294 // We have to check that effects and the code they emit are consistent, ie i
f an effect | 294 // We have to check that effects and the code they emit are consistent, ie i
f an effect |
| 295 // asks for dst color, then the emit code needs to follow suit | 295 // asks for dst color, then the emit code needs to follow suit |
| 296 verify(fp); | 296 verify(fp); |
| 297 fFragmentProcessors->fProcs.push_back(ifp); | 297 fFragmentProcessors->fProcs.push_back(ifp); |
| 298 } | 298 } |
| 299 | 299 |
| 300 void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& gp, | 300 void GrGLProgramBuilder::emitAndInstallProc(const GrPrimitiveProcessor& gp, |
| 301 const char* outColor, | 301 const char* outColor, |
| 302 const char* outCoverage) { | 302 const char* outCoverage) { |
| 303 SkASSERT(!fGeometryProcessor); | 303 SkASSERT(!fGeometryProcessor); |
| 304 fGeometryProcessor = SkNEW(GrGLInstalledGeoProc); | 304 fGeometryProcessor = new GrGLInstalledGeoProc; |
| 305 | 305 |
| 306 const GrBatchTracker& bt = this->batchTracker(); | 306 const GrBatchTracker& bt = this->batchTracker(); |
| 307 fGeometryProcessor->fGLProc.reset(gp.createGLInstance(bt, *fGpu->glCaps().gl
slCaps())); | 307 fGeometryProcessor->fGLProc.reset(gp.createGLInstance(bt, *fGpu->glCaps().gl
slCaps())); |
| 308 | 308 |
| 309 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures()); | 309 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures()); |
| 310 this->emitSamplers(gp, &samplers, fGeometryProcessor); | 310 this->emitSamplers(gp, &samplers, fGeometryProcessor); |
| 311 | 311 |
| 312 GrGLGeometryProcessor::EmitArgs args(this, gp, bt, outColor, outCoverage, sa
mplers, | 312 GrGLGeometryProcessor::EmitArgs args(this, gp, bt, outColor, outCoverage, sa
mplers, |
| 313 fCoordTransforms, &fOutCoords); | 313 fCoordTransforms, &fOutCoords); |
| 314 fGeometryProcessor->fGLProc->emitCode(args); | 314 fGeometryProcessor->fGLProc->emitCode(args); |
| 315 | 315 |
| 316 // We have to check that effects and the code they emit are consistent, ie i
f an effect | 316 // We have to check that effects and the code they emit are consistent, ie i
f an effect |
| 317 // asks for dst color, then the emit code needs to follow suit | 317 // asks for dst color, then the emit code needs to follow suit |
| 318 verify(gp); | 318 verify(gp); |
| 319 } | 319 } |
| 320 | 320 |
| 321 void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp, | 321 void GrGLProgramBuilder::emitAndInstallXferProc(const GrXferProcessor& xp, |
| 322 const GrGLSLExpr4& colorIn, | 322 const GrGLSLExpr4& colorIn, |
| 323 const GrGLSLExpr4& coverageIn) { | 323 const GrGLSLExpr4& coverageIn) { |
| 324 // Program builders have a bit of state we need to clear with each effect | 324 // Program builders have a bit of state we need to clear with each effect |
| 325 AutoStageAdvance adv(this); | 325 AutoStageAdvance adv(this); |
| 326 | 326 |
| 327 SkASSERT(!fXferProcessor); | 327 SkASSERT(!fXferProcessor); |
| 328 fXferProcessor = SkNEW(GrGLInstalledXferProc); | 328 fXferProcessor = new GrGLInstalledXferProc; |
| 329 | 329 |
| 330 fXferProcessor->fGLProc.reset(xp.createGLInstance()); | 330 fXferProcessor->fGLProc.reset(xp.createGLInstance()); |
| 331 | 331 |
| 332 // Enable dual source secondary output if we have one | 332 // Enable dual source secondary output if we have one |
| 333 if (xp.hasSecondaryOutput()) { | 333 if (xp.hasSecondaryOutput()) { |
| 334 fFS.enableSecondaryOutput(); | 334 fFS.enableSecondaryOutput(); |
| 335 } | 335 } |
| 336 | 336 |
| 337 if (this->ctxInfo().caps()->glslCaps()->mustDeclareFragmentShaderOutput()) { | 337 if (this->ctxInfo().caps()->glslCaps()->mustDeclareFragmentShaderOutput()) { |
| 338 fFS.enableCustomOutput(); | 338 fFS.enableCustomOutput(); |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 485 GL_CALL(DeleteProgram(programID)); | 485 GL_CALL(DeleteProgram(programID)); |
| 486 cleanupShaders(shaderIDs); | 486 cleanupShaders(shaderIDs); |
| 487 } | 487 } |
| 488 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { | 488 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { |
| 489 for (int i = 0; i < shaderIDs.count(); ++i) { | 489 for (int i = 0; i < shaderIDs.count(); ++i) { |
| 490 GL_CALL(DeleteShader(shaderIDs[i])); | 490 GL_CALL(DeleteShader(shaderIDs[i])); |
| 491 } | 491 } |
| 492 } | 492 } |
| 493 | 493 |
| 494 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { | 494 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { |
| 495 return SkNEW_ARGS(GrGLProgram, (fGpu, this->desc(), fUniformHandles, program
ID, fUniforms, | 495 return new GrGLProgram(fGpu, this->desc(), fUniformHandles, programID, fUnif
orms, |
| 496 fGeometryProcessor, fXferProcessor, fFragmen
tProcessors.get(), | 496 fGeometryProcessor, fXferProcessor, fFragmentProcesso
rs.get(), |
| 497 &fSamplerUniforms)); | 497 &fSamplerUniforms); |
| 498 } | 498 } |
| 499 | 499 |
| 500 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 500 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 501 | 501 |
| 502 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 502 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| 503 int numProcs = fProcs.count(); | 503 int numProcs = fProcs.count(); |
| 504 for (int e = 0; e < numProcs; ++e) { | 504 for (int e = 0; e < numProcs; ++e) { |
| 505 SkDELETE(fProcs[e]); | 505 delete fProcs[e]; |
| 506 } | 506 } |
| 507 } | 507 } |
| OLD | NEW |