| 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 "GrAutoLocaleSetter.h" | 10 #include "GrAutoLocaleSetter.h" |
| 11 #include "GrCoordTransform.h" | 11 #include "GrCoordTransform.h" |
| 12 #include "GrGLProgramBuilder.h" | 12 #include "GrGLProgramBuilder.h" |
| 13 #include "GrTexture.h" | 13 #include "GrTexture.h" |
| 14 #include "SkRTConf.h" | 14 #include "SkRTConf.h" |
| 15 #include "SkTraceEvent.h" | 15 #include "SkTraceEvent.h" |
| 16 #include "gl/GrGLFragmentProcessor.h" | 16 #include "gl/GrGLFragmentProcessor.h" |
| 17 #include "gl/GrGLGeometryProcessor.h" | 17 #include "gl/GrGLGeometryProcessor.h" |
| 18 #include "gl/GrGLGpu.h" | 18 #include "gl/GrGLGpu.h" |
| 19 #include "gl/GrGLProgram.h" | 19 #include "gl/GrGLProgram.h" |
| 20 #include "gl/GrGLSLPrettyPrint.h" | 20 #include "gl/GrGLSLPrettyPrint.h" |
| 21 #include "gl/GrGLXferProcessor.h" | 21 #include "gl/GrGLXferProcessor.h" |
| 22 #include "gl/builders/GrGLShaderStringBuilder.h" | 22 #include "gl/builders/GrGLShaderStringBuilder.h" |
| 23 #include "glsl/GrGLSLCaps.h" | 23 #include "glsl/GrGLSLCaps.h" |
| 24 #include "glsl/GrGLSLProgramDataManager.h" | 24 #include "glsl/GrGLSLProgramDataManager.h" |
| 25 #include "glsl/GrGLSLTextureSampler.h" | 25 #include "glsl/GrGLSLTextureSampler.h" |
| 26 | 26 |
| 27 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) | 27 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) |
| 28 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) | 28 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) |
| 29 | 29 |
| 30 const int GrGLProgramBuilder::kVarsPerBlock = 8; | |
| 31 | |
| 32 GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp
u) { | 30 GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp
u) { |
| 33 GrAutoLocaleSetter als("C"); | 31 GrAutoLocaleSetter als("C"); |
| 34 | 32 |
| 35 // create a builder. This will be handed off to effects so they can use it
to add | 33 // create a builder. This will be handed off to effects so they can use it
to add |
| 36 // uniforms, varyings, textures, etc | 34 // uniforms, varyings, textures, etc |
| 37 SkAutoTDelete<GrGLProgramBuilder> builder(new GrGLProgramBuilder(gpu, args))
; | 35 SkAutoTDelete<GrGLProgramBuilder> builder(new GrGLProgramBuilder(gpu, args))
; |
| 38 | 36 |
| 39 GrGLProgramBuilder* pb = builder.get(); | 37 GrGLProgramBuilder* pb = builder.get(); |
| 40 | 38 |
| 41 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can | 39 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can |
| 42 // seed correctly here | 40 // seed correctly here |
| 43 GrGLSLExpr4 inputColor; | 41 GrGLSLExpr4 inputColor; |
| 44 GrGLSLExpr4 inputCoverage; | 42 GrGLSLExpr4 inputCoverage; |
| 45 | 43 |
| 46 if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { | 44 if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { |
| 47 return nullptr; | 45 return nullptr; |
| 48 } | 46 } |
| 49 | 47 |
| 50 return pb->finalize(); | 48 return pb->finalize(); |
| 51 } | 49 } |
| 52 | 50 |
| 53 ///////////////////////////////////////////////////////////////////////////// | 51 ///////////////////////////////////////////////////////////////////////////// |
| 54 | 52 |
| 55 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) | 53 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) |
| 56 : fVS(this) | 54 : INHERITED(args) |
| 57 , fGS(this) | |
| 58 , fFS(this, args.fDesc->header().fFragPosKey) | |
| 59 , fStageIndex(-1) | |
| 60 , fGeometryProcessor(nullptr) | 55 , fGeometryProcessor(nullptr) |
| 61 , fXferProcessor(nullptr) | 56 , fXferProcessor(nullptr) |
| 62 , fArgs(args) | |
| 63 , fGpu(gpu) | 57 , fGpu(gpu) |
| 64 , fUniforms(kVarsPerBlock) | 58 , fUniforms(kVarsPerBlock) |
| 65 , fSamplerUniforms(4) | 59 , fSamplerUniforms(4) |
| 66 , fSeparableVaryingInfos(kVarsPerBlock) { | 60 , fSeparableVaryingInfos(kVarsPerBlock) { |
| 67 } | 61 } |
| 68 | 62 |
| 69 void GrGLProgramBuilder::addVarying(const char* name, | 63 void GrGLProgramBuilder::addVarying(const char* name, |
| 70 GrGLVarying* varying, | 64 GrGLSLVarying* varying, |
| 71 GrSLPrecision precision) { | 65 GrSLPrecision precision) { |
| 72 SkASSERT(varying); | 66 SkASSERT(varying); |
| 73 if (varying->vsVarying()) { | 67 if (varying->vsVarying()) { |
| 74 fVS.addVarying(name, precision, varying); | 68 fVS.addVarying(name, precision, varying); |
| 75 } | 69 } |
| 76 if (this->primitiveProcessor().willUseGeoShader()) { | 70 if (this->primitiveProcessor().willUseGeoShader()) { |
| 77 fGS.addVarying(name, precision, varying); | 71 fGS.addVarying(name, precision, varying); |
| 78 } | 72 } |
| 79 if (varying->fsVarying()) { | 73 if (varying->fsVarying()) { |
| 80 fFS.addVarying(varying, precision); | 74 fFS.addVarying(varying, precision); |
| 81 } | 75 } |
| 82 } | 76 } |
| 83 | 77 |
| 84 void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att
ribute* input, | 78 void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att
ribute* input, |
| 85 const char* output) { | 79 const char* output) { |
| 86 GrSLType type = GrVertexAttribTypeToSLType(input->fType); | 80 GrSLType type = GrVertexAttribTypeToSLType(input->fType); |
| 87 GrGLVertToFrag v(type); | 81 GrGLSLVertToFrag v(type); |
| 88 this->addVarying(input->fName, &v); | 82 this->addVarying(input->fName, &v); |
| 89 fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); | 83 fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); |
| 90 fFS.codeAppendf("%s = %s;", output, v.fsIn()); | 84 fFS.codeAppendf("%s = %s;", output, v.fsIn()); |
| 91 } | 85 } |
| 92 | 86 |
| 93 GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVaryi
ng( | 87 GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVaryi
ng( |
| 94 const ch
ar* name, | 88 const ch
ar* name, |
| 95 GrGLVert
ToFrag* v, | 89 GrGLSLVe
rtToFrag* v, |
| 96 GrSLPrec
ision fsPrecision) { | 90 GrSLPrec
ision fsPrecision) { |
| 97 // This call is not used for non-NVPR backends. | 91 // This call is not used for non-NVPR backends. |
| 98 SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport() && | 92 SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport() && |
| 99 fArgs.fPrimitiveProcessor->isPathRendering() && | 93 fArgs.fPrimitiveProcessor->isPathRendering() && |
| 100 !fArgs.fPrimitiveProcessor->willUseGeoShader() && | 94 !fArgs.fPrimitiveProcessor->willUseGeoShader() && |
| 101 fArgs.fPrimitiveProcessor->numAttribs() == 0); | 95 fArgs.fPrimitiveProcessor->numAttribs() == 0); |
| 102 this->addVarying(name, v, fsPrecision); | 96 this->addVarying(name, v, fsPrecision); |
| 103 SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back(); | 97 SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back(); |
| 104 varyingInfo.fVariable = this->getFragmentShaderBuilder()->fInputs.back(); | 98 varyingInfo.fVariable = this->getFragmentShaderBuilder()->fInputs.back(); |
| 105 varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1; | 99 varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1; |
| 106 return SeparableVaryingHandle(varyingInfo.fLocation); | 100 return SeparableVaryingHandle(varyingInfo.fLocation); |
| 107 } | 101 } |
| 108 | 102 |
| 109 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* na
me, bool mangle) { | |
| 110 if ('\0' == prefix) { | |
| 111 *out = name; | |
| 112 } else { | |
| 113 out->printf("%c%s", prefix, name); | |
| 114 } | |
| 115 if (mangle) { | |
| 116 if (out->endsWith('_')) { | |
| 117 // Names containing "__" are reserved. | |
| 118 out->append("x"); | |
| 119 } | |
| 120 out->appendf("_Stage%d%s", fStageIndex, fFS.getMangleString().c_str()); | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 GrGLSLProgramDataManager::UniformHandle GrGLProgramBuilder::internalAddUniformAr
ray( | 103 GrGLSLProgramDataManager::UniformHandle GrGLProgramBuilder::internalAddUniformAr
ray( |
| 125 uint32_t visibil
ity, | 104 uint32_t visibil
ity, |
| 126 GrSLType type, | 105 GrSLType type, |
| 127 GrSLPrecision pr
ecision, | 106 GrSLPrecision pr
ecision, |
| 128 const char* name
, | 107 const char* name
, |
| 129 bool mangleName, | 108 bool mangleName, |
| 130 int count, | 109 int count, |
| 131 const char** out
Name) { | 110 const char** out
Name) { |
| 132 SkASSERT(name && strlen(name)); | 111 SkASSERT(name && strlen(name)); |
| 133 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); | 112 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 152 uni.fVariable.setArrayCount(count); | 131 uni.fVariable.setArrayCount(count); |
| 153 uni.fVisibility = visibility; | 132 uni.fVisibility = visibility; |
| 154 uni.fVariable.setPrecision(precision); | 133 uni.fVariable.setPrecision(precision); |
| 155 | 134 |
| 156 if (outName) { | 135 if (outName) { |
| 157 *outName = uni.fVariable.c_str(); | 136 *outName = uni.fVariable.c_str(); |
| 158 } | 137 } |
| 159 return GrGLSLProgramDataManager::UniformHandle(fUniforms.count() - 1); | 138 return GrGLSLProgramDataManager::UniformHandle(fUniforms.count() - 1); |
| 160 } | 139 } |
| 161 | 140 |
| 162 void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility, | 141 void GrGLProgramBuilder::onAppendUniformDecls(ShaderVisibility visibility, SkStr
ing* out) const { |
| 163 SkString* out) const { | |
| 164 for (int i = 0; i < fUniforms.count(); ++i) { | 142 for (int i = 0; i < fUniforms.count(); ++i) { |
| 165 if (fUniforms[i].fVisibility & visibility) { | 143 if (fUniforms[i].fVisibility & visibility) { |
| 166 fUniforms[i].fVariable.appendDecl(this->glslCaps(), out); | 144 fUniforms[i].fVariable.appendDecl(this->glslCaps(), out); |
| 167 out->append(";\n"); | 145 out->append(";\n"); |
| 168 } | 146 } |
| 169 } | 147 } |
| 170 } | 148 } |
| 171 | 149 |
| 172 const GrGLContextInfo& GrGLProgramBuilder::ctxInfo() const { | |
| 173 return fGpu->ctxInfo(); | |
| 174 } | |
| 175 | |
| 176 const GrGLSLCaps* GrGLProgramBuilder::glslCaps() const { | 150 const GrGLSLCaps* GrGLProgramBuilder::glslCaps() const { |
| 177 return this->ctxInfo().caps()->glslCaps(); | 151 return this->fGpu->ctxInfo().caps()->glslCaps(); |
| 178 } | 152 } |
| 179 | 153 |
| 180 bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
4* inputCoverage) { | 154 bool GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, GrGLSLExpr
4* inputCoverage) { |
| 181 // First we loop over all of the installed processors and collect coord tran
sforms. These will | 155 // First we loop over all of the installed processors and collect coord tran
sforms. These will |
| 182 // be sent to the GrGLPrimitiveProcessor in its emitCode function | 156 // be sent to the GrGLPrimitiveProcessor in its emitCode function |
| 183 const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); | 157 const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); |
| 184 int totalTextures = primProc.numTextures(); | 158 int totalTextures = primProc.numTextures(); |
| 185 const int maxTextureUnits = fGpu->glCaps().maxFragmentTextureUnits(); | 159 const int maxTextureUnits = fGpu->glCaps().maxFragmentTextureUnits(); |
| 186 | 160 |
| 187 for (int i = 0; i < this->pipeline().numFragmentProcessors(); i++) { | 161 for (int i = 0; i < this->pipeline().numFragmentProcessors(); i++) { |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 SkASSERT(!fXferProcessor); | 297 SkASSERT(!fXferProcessor); |
| 324 fXferProcessor = new GrGLInstalledXferProc; | 298 fXferProcessor = new GrGLInstalledXferProc; |
| 325 | 299 |
| 326 fXferProcessor->fGLProc.reset(xp.createGLInstance()); | 300 fXferProcessor->fGLProc.reset(xp.createGLInstance()); |
| 327 | 301 |
| 328 // Enable dual source secondary output if we have one | 302 // Enable dual source secondary output if we have one |
| 329 if (xp.hasSecondaryOutput()) { | 303 if (xp.hasSecondaryOutput()) { |
| 330 fFS.enableSecondaryOutput(); | 304 fFS.enableSecondaryOutput(); |
| 331 } | 305 } |
| 332 | 306 |
| 333 if (this->ctxInfo().caps()->glslCaps()->mustDeclareFragmentShaderOutput()) { | 307 if (this->glslCaps()->mustDeclareFragmentShaderOutput()) { |
| 334 fFS.enableCustomOutput(); | 308 fFS.enableCustomOutput(); |
| 335 } | 309 } |
| 336 | 310 |
| 337 SkString openBrace; | 311 SkString openBrace; |
| 338 openBrace.printf("{ // Xfer Processor: %s\n", xp.name()); | 312 openBrace.printf("{ // Xfer Processor: %s\n", xp.name()); |
| 339 fFS.codeAppend(openBrace.c_str()); | 313 fFS.codeAppend(openBrace.c_str()); |
| 340 | 314 |
| 341 SkSTArray<4, GrGLSLTextureSampler> samplers(xp.numTextures()); | 315 SkSTArray<4, GrGLSLTextureSampler> samplers(xp.numTextures()); |
| 342 this->emitSamplers(xp, &samplers, fXferProcessor); | 316 this->emitSamplers(xp, &samplers, fXferProcessor); |
| 343 | 317 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 SkTDArray<GrGLuint> shadersToDelete; | 390 SkTDArray<GrGLuint> shadersToDelete; |
| 417 fVS.finalize(kVertex_Visibility); | 391 fVS.finalize(kVertex_Visibility); |
| 418 if (!this->compileAndAttachShaders(fVS, programID, GR_GL_VERTEX_SHADER, &sha
dersToDelete)) { | 392 if (!this->compileAndAttachShaders(fVS, programID, GR_GL_VERTEX_SHADER, &sha
dersToDelete)) { |
| 419 this->cleanupProgram(programID, shadersToDelete); | 393 this->cleanupProgram(programID, shadersToDelete); |
| 420 return nullptr; | 394 return nullptr; |
| 421 } | 395 } |
| 422 | 396 |
| 423 // NVPR actually requires a vertex shader to compile | 397 // NVPR actually requires a vertex shader to compile |
| 424 bool useNvpr = primitiveProcessor().isPathRendering(); | 398 bool useNvpr = primitiveProcessor().isPathRendering(); |
| 425 if (!useNvpr) { | 399 if (!useNvpr) { |
| 426 fVS.bindVertexAttributes(programID); | 400 const GrPrimitiveProcessor& primProc = this->primitiveProcessor(); |
| 401 |
| 402 int vaCount = primProc.numAttribs(); |
| 403 for (int i = 0; i < vaCount; i++) { |
| 404 GL_CALL(BindAttribLocation(programID, i, primProc.getAttrib(i).fName
)); |
| 405 } |
| 427 } | 406 } |
| 428 | 407 |
| 429 fFS.finalize(kFragment_Visibility); | 408 fFS.finalize(kFragment_Visibility); |
| 430 if (!this->compileAndAttachShaders(fFS, programID, GR_GL_FRAGMENT_SHADER, &s
hadersToDelete)) { | 409 if (!this->compileAndAttachShaders(fFS, programID, GR_GL_FRAGMENT_SHADER, &s
hadersToDelete)) { |
| 431 this->cleanupProgram(programID, shadersToDelete); | 410 this->cleanupProgram(programID, shadersToDelete); |
| 432 return nullptr; | 411 return nullptr; |
| 433 } | 412 } |
| 434 | 413 |
| 435 this->bindProgramResourceLocations(programID); | 414 this->bindProgramResourceLocations(programID); |
| 436 | 415 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 453 | 432 |
| 454 void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { | 433 void GrGLProgramBuilder::bindProgramResourceLocations(GrGLuint programID) { |
| 455 if (fGpu->glCaps().bindUniformLocationSupport()) { | 434 if (fGpu->glCaps().bindUniformLocationSupport()) { |
| 456 int count = fUniforms.count(); | 435 int count = fUniforms.count(); |
| 457 for (int i = 0; i < count; ++i) { | 436 for (int i = 0; i < count; ++i) { |
| 458 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_s
tr())); | 437 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_s
tr())); |
| 459 fUniforms[i].fLocation = i; | 438 fUniforms[i].fLocation = i; |
| 460 } | 439 } |
| 461 } | 440 } |
| 462 | 441 |
| 463 fFS.bindFragmentShaderLocations(programID); | 442 const GrGLCaps& caps = this->gpu()->glCaps(); |
| 443 if (fFS.hasCustomColorOutput() && caps.bindFragDataLocationSupport()) { |
| 444 GL_CALL(BindFragDataLocation(programID, 0, |
| 445 GrGLFragmentShaderBuilder::DeclaredColorOut
putName())); |
| 446 } |
| 447 if (fFS.hasSecondaryOutput() && caps.glslCaps()->mustDeclareFragmentShaderOu
tput()) { |
| 448 GL_CALL(BindFragDataLocationIndexed(programID, 0, 1, |
| 449 GrGLFragmentShaderBuilder::DeclaredSecondary
ColorOutputName())); |
| 450 } |
| 464 | 451 |
| 465 // handle NVPR separable varyings | 452 // handle NVPR separable varyings |
| 466 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() || | 453 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() || |
| 467 !fGpu->glPathRendering()->shouldBindFragmentInputs()) { | 454 !fGpu->glPathRendering()->shouldBindFragmentInputs()) { |
| 468 return; | 455 return; |
| 469 } | 456 } |
| 470 int count = fSeparableVaryingInfos.count(); | 457 int count = fSeparableVaryingInfos.count(); |
| 471 for (int i = 0; i < count; ++i) { | 458 for (int i = 0; i < count; ++i) { |
| 472 GL_CALL(BindFragmentInputLocation(programID, | 459 GL_CALL(BindFragmentInputLocation(programID, |
| 473 i, | 460 i, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 } | 531 } |
| 545 | 532 |
| 546 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 533 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 547 | 534 |
| 548 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 535 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| 549 int numProcs = fProcs.count(); | 536 int numProcs = fProcs.count(); |
| 550 for (int i = 0; i < numProcs; ++i) { | 537 for (int i = 0; i < numProcs; ++i) { |
| 551 delete fProcs[i]; | 538 delete fProcs[i]; |
| 552 } | 539 } |
| 553 } | 540 } |
| OLD | NEW |