| 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 "GrGLPathProgramBuilder.h" | |
| 13 #include "GrGLProgramBuilder.h" | 12 #include "GrGLProgramBuilder.h" |
| 14 #include "GrTexture.h" | 13 #include "GrTexture.h" |
| 15 #include "SkRTConf.h" | 14 #include "SkRTConf.h" |
| 16 #include "SkTraceEvent.h" | 15 #include "SkTraceEvent.h" |
| 17 #include "gl/GrGLGeometryProcessor.h" | 16 #include "gl/GrGLGeometryProcessor.h" |
| 18 #include "gl/GrGLGpu.h" | 17 #include "gl/GrGLGpu.h" |
| 19 #include "gl/GrGLPathProcessor.h" | 18 #include "gl/GrGLPathProcessor.h" |
| 20 #include "gl/GrGLProgram.h" | 19 #include "gl/GrGLProgram.h" |
| 21 #include "gl/GrGLSLPrettyPrint.h" | 20 #include "gl/GrGLSLPrettyPrint.h" |
| 22 #include "gl/GrGLXferProcessor.h" | 21 #include "gl/GrGLXferProcessor.h" |
| 23 #include "glsl/GrGLSLCaps.h" | 22 #include "glsl/GrGLSLCaps.h" |
| 24 | 23 |
| 25 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) | 24 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) |
| 26 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) | 25 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) |
| 27 | 26 |
| 28 const int GrGLProgramBuilder::kVarsPerBlock = 8; | 27 const int GrGLProgramBuilder::kVarsPerBlock = 8; |
| 29 | 28 |
| 30 GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp
u) { | 29 GrGLProgram* GrGLProgramBuilder::CreateProgram(const DrawArgs& args, GrGLGpu* gp
u) { |
| 31 GrAutoLocaleSetter als("C"); | 30 GrAutoLocaleSetter als("C"); |
| 32 | 31 |
| 33 // create a builder. This will be handed off to effects so they can use it
to add | 32 // create a builder. This will be handed off to effects so they can use it
to add |
| 34 // uniforms, varyings, textures, etc | 33 // uniforms, varyings, textures, etc |
| 35 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(args, gpu)); | 34 SkAutoTDelete<GrGLProgramBuilder> builder(new GrGLProgramBuilder(gpu, args))
; |
| 36 | 35 |
| 37 GrGLProgramBuilder* pb = builder.get(); | 36 GrGLProgramBuilder* pb = builder.get(); |
| 38 | 37 |
| 39 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can | 38 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can |
| 40 // seed correctly here | 39 // seed correctly here |
| 41 GrGLSLExpr4 inputColor; | 40 GrGLSLExpr4 inputColor; |
| 42 GrGLSLExpr4 inputCoverage; | 41 GrGLSLExpr4 inputCoverage; |
| 43 | 42 |
| 44 if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { | 43 if (!pb->emitAndInstallProcs(&inputColor, &inputCoverage)) { |
| 45 return nullptr; | 44 return nullptr; |
| 46 } | 45 } |
| 47 | 46 |
| 48 return pb->finalize(); | 47 return pb->finalize(); |
| 49 } | 48 } |
| 50 | 49 |
| 51 GrGLProgramBuilder* GrGLProgramBuilder::CreateProgramBuilder(const DrawArgs& arg
s, | |
| 52 GrGLGpu* gpu) { | |
| 53 if (args.fPrimitiveProcessor->isPathRendering()) { | |
| 54 SkASSERT(gpu->glCaps().shaderCaps()->pathRenderingSupport() && | |
| 55 !args.fPrimitiveProcessor->willUseGeoShader() && | |
| 56 args.fPrimitiveProcessor->numAttribs() == 0); | |
| 57 return new GrGLPathProgramBuilder(gpu, args); | |
| 58 } else { | |
| 59 return new GrGLProgramBuilder(gpu, args); | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 ///////////////////////////////////////////////////////////////////////////// | 50 ///////////////////////////////////////////////////////////////////////////// |
| 64 | 51 |
| 65 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) | 52 GrGLProgramBuilder::GrGLProgramBuilder(GrGLGpu* gpu, const DrawArgs& args) |
| 66 : fVS(this) | 53 : fVS(this) |
| 67 , fGS(this) | 54 , fGS(this) |
| 68 , fFS(this, args.fDesc->header().fFragPosKey) | 55 , fFS(this, args.fDesc->header().fFragPosKey) |
| 69 , fOutOfStage(true) | 56 , fOutOfStage(true) |
| 70 , fStageIndex(-1) | 57 , fStageIndex(-1) |
| 71 , fGeometryProcessor(nullptr) | 58 , fGeometryProcessor(nullptr) |
| 72 , fXferProcessor(nullptr) | 59 , fXferProcessor(nullptr) |
| 73 , fArgs(args) | 60 , fArgs(args) |
| 74 , fGpu(gpu) | 61 , fGpu(gpu) |
| 75 , fUniforms(kVarsPerBlock) | 62 , fUniforms(kVarsPerBlock) |
| 76 , fSamplerUniforms(4) { | 63 , fSamplerUniforms(4) |
| 64 , fSeparableVaryingInfos(kVarsPerBlock) { |
| 77 } | 65 } |
| 78 | 66 |
| 79 void GrGLProgramBuilder::addVarying(const char* name, | 67 void GrGLProgramBuilder::addVarying(const char* name, |
| 80 GrGLVarying* varying, | 68 GrGLVarying* varying, |
| 81 GrSLPrecision fsPrecision) { | 69 GrSLPrecision fsPrecision) { |
| 82 SkASSERT(varying); | 70 SkASSERT(varying); |
| 83 if (varying->vsVarying()) { | 71 if (varying->vsVarying()) { |
| 84 fVS.addVarying(name, varying); | 72 fVS.addVarying(name, varying); |
| 85 } | 73 } |
| 86 if (this->primitiveProcessor().willUseGeoShader()) { | 74 if (this->primitiveProcessor().willUseGeoShader()) { |
| 87 fGS.addVarying(name, varying); | 75 fGS.addVarying(name, varying); |
| 88 } | 76 } |
| 89 if (varying->fsVarying()) { | 77 if (varying->fsVarying()) { |
| 90 fFS.addVarying(varying, fsPrecision); | 78 fFS.addVarying(varying, fsPrecision); |
| 91 } | 79 } |
| 92 } | 80 } |
| 93 | 81 |
| 94 void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att
ribute* input, | 82 void GrGLProgramBuilder::addPassThroughAttribute(const GrPrimitiveProcessor::Att
ribute* input, |
| 95 const char* output) { | 83 const char* output) { |
| 96 GrSLType type = GrVertexAttribTypeToSLType(input->fType); | 84 GrSLType type = GrVertexAttribTypeToSLType(input->fType); |
| 97 GrGLVertToFrag v(type); | 85 GrGLVertToFrag v(type); |
| 98 this->addVarying(input->fName, &v); | 86 this->addVarying(input->fName, &v); |
| 99 fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); | 87 fVS.codeAppendf("%s = %s;", v.vsOut(), input->fName); |
| 100 fFS.codeAppendf("%s = %s;", output, v.fsIn()); | 88 fFS.codeAppendf("%s = %s;", output, v.fsIn()); |
| 101 } | 89 } |
| 102 | 90 |
| 103 GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVaryi
ng(const char*, | 91 GrGLProgramBuilder::SeparableVaryingHandle GrGLProgramBuilder::addSeparableVaryi
ng( |
| 104
GrGLVertToFrag*, | 92 const ch
ar* name, |
| 105
GrSLPrecision) { | 93 GrGLVert
ToFrag* v, |
| 106 // This call is not used for non-NVPR backends. However, the polymorphism be
tween | 94 GrSLPrec
ision fsPrecision) { |
| 107 // GrPrimitiveProcessor, GrGLPrimitiveProcessor and GrGLProgramBuilder does
not allow for | 95 // This call is not used for non-NVPR backends. |
| 108 // a system where GrGLPathProcessor would be able to refer to a primitive-sp
ecific builder | 96 SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport() && |
| 109 // that would understand separable varyings. Thus separable varyings need to
be present | 97 fArgs.fPrimitiveProcessor->isPathRendering() && |
| 110 // early in the inheritance chain of builders. | 98 !fArgs.fPrimitiveProcessor->willUseGeoShader() && |
| 111 SkASSERT(false); | 99 fArgs.fPrimitiveProcessor->numAttribs() == 0); |
| 112 return SeparableVaryingHandle(); | 100 this->addVarying(name, v, fsPrecision); |
| 101 SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back(); |
| 102 varyingInfo.fVariable = this->getFragmentShaderBuilder()->fInputs.back(); |
| 103 varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1; |
| 104 return SeparableVaryingHandle(varyingInfo.fLocation); |
| 113 } | 105 } |
| 114 | 106 |
| 115 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* na
me) { | 107 void GrGLProgramBuilder::nameVariable(SkString* out, char prefix, const char* na
me) { |
| 116 if ('\0' == prefix) { | 108 if ('\0' == prefix) { |
| 117 *out = name; | 109 *out = name; |
| 118 } else { | 110 } else { |
| 119 out->printf("%c%s", prefix, name); | 111 out->printf("%c%s", prefix, name); |
| 120 } | 112 } |
| 121 if (!fOutOfStage) { | 113 if (!fOutOfStage) { |
| 122 if (out->endsWith('_')) { | 114 if (out->endsWith('_')) { |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= nullptr; | 425 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= nullptr; |
| 434 if (usingBindUniform) { | 426 if (usingBindUniform) { |
| 435 int count = fUniforms.count(); | 427 int count = fUniforms.count(); |
| 436 for (int i = 0; i < count; ++i) { | 428 for (int i = 0; i < count; ++i) { |
| 437 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_s
tr())); | 429 GL_CALL(BindUniformLocation(programID, i, fUniforms[i].fVariable.c_s
tr())); |
| 438 fUniforms[i].fLocation = i; | 430 fUniforms[i].fLocation = i; |
| 439 } | 431 } |
| 440 } | 432 } |
| 441 | 433 |
| 442 fFS.bindFragmentShaderLocations(programID); | 434 fFS.bindFragmentShaderLocations(programID); |
| 435 |
| 436 // handle NVPR separable varyings |
| 437 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() || |
| 438 !fGpu->glPathRendering()->shouldBindFragmentInputs()) { |
| 439 return; |
| 440 } |
| 441 int count = fSeparableVaryingInfos.count(); |
| 442 for (int i = 0; i < count; ++i) { |
| 443 GL_CALL(BindFragmentInputLocation(programID, |
| 444 i, |
| 445 fSeparableVaryingInfos[i].fVariable.c_
str())); |
| 446 fSeparableVaryingInfos[i].fLocation = i; |
| 447 } |
| 443 } | 448 } |
| 444 | 449 |
| 445 bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) { | 450 bool GrGLProgramBuilder::checkLinkStatus(GrGLuint programID) { |
| 446 GrGLint linked = GR_GL_INIT_ZERO; | 451 GrGLint linked = GR_GL_INIT_ZERO; |
| 447 GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked)); | 452 GL_CALL(GetProgramiv(programID, GR_GL_LINK_STATUS, &linked)); |
| 448 if (!linked) { | 453 if (!linked) { |
| 449 GrGLint infoLen = GR_GL_INIT_ZERO; | 454 GrGLint infoLen = GR_GL_INIT_ZERO; |
| 450 GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen)); | 455 GL_CALL(GetProgramiv(programID, GR_GL_INFO_LOG_LENGTH, &infoLen)); |
| 451 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger | 456 SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger |
| 452 if (infoLen > 0) { | 457 if (infoLen > 0) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 469 void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { | 474 void GrGLProgramBuilder::resolveProgramResourceLocations(GrGLuint programID) { |
| 470 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= nullptr; | 475 bool usingBindUniform = fGpu->glInterface()->fFunctions.fBindUniformLocation
!= nullptr; |
| 471 if (!usingBindUniform) { | 476 if (!usingBindUniform) { |
| 472 int count = fUniforms.count(); | 477 int count = fUniforms.count(); |
| 473 for (int i = 0; i < count; ++i) { | 478 for (int i = 0; i < count; ++i) { |
| 474 GrGLint location; | 479 GrGLint location; |
| 475 GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVa
riable.c_str())); | 480 GL_CALL_RET(location, GetUniformLocation(programID, fUniforms[i].fVa
riable.c_str())); |
| 476 fUniforms[i].fLocation = location; | 481 fUniforms[i].fLocation = location; |
| 477 } | 482 } |
| 478 } | 483 } |
| 484 |
| 485 // handle NVPR separable varyings |
| 486 if (!fGpu->glCaps().shaderCaps()->pathRenderingSupport() || |
| 487 !fGpu->glPathRendering()->shouldBindFragmentInputs()) { |
| 488 return; |
| 489 } |
| 490 int count = fSeparableVaryingInfos.count(); |
| 491 for (int i = 0; i < count; ++i) { |
| 492 GrGLint location; |
| 493 GL_CALL_RET(location, |
| 494 GetProgramResourceLocation(programID, |
| 495 GR_GL_FRAGMENT_INPUT, |
| 496 fSeparableVaryingInfos[i].fVariab
le.c_str())); |
| 497 fSeparableVaryingInfos[i].fLocation = location; |
| 498 } |
| 479 } | 499 } |
| 480 | 500 |
| 481 void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGL
uint>& shaderIDs) { | 501 void GrGLProgramBuilder::cleanupProgram(GrGLuint programID, const SkTDArray<GrGL
uint>& shaderIDs) { |
| 482 GL_CALL(DeleteProgram(programID)); | 502 GL_CALL(DeleteProgram(programID)); |
| 483 cleanupShaders(shaderIDs); | 503 cleanupShaders(shaderIDs); |
| 484 } | 504 } |
| 485 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { | 505 void GrGLProgramBuilder::cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs) { |
| 486 for (int i = 0; i < shaderIDs.count(); ++i) { | 506 for (int i = 0; i < shaderIDs.count(); ++i) { |
| 487 GL_CALL(DeleteShader(shaderIDs[i])); | 507 GL_CALL(DeleteShader(shaderIDs[i])); |
| 488 } | 508 } |
| 489 } | 509 } |
| 490 | 510 |
| 491 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { | 511 GrGLProgram* GrGLProgramBuilder::createProgram(GrGLuint programID) { |
| 492 return new GrGLProgram(fGpu, this->desc(), fUniformHandles, programID, fUnif
orms, | 512 return new GrGLProgram(fGpu, this->desc(), fUniformHandles, programID, fUnif
orms, |
| 513 fSeparableVaryingInfos, |
| 493 fGeometryProcessor, fXferProcessor, fFragmentProcesso
rs.get(), | 514 fGeometryProcessor, fXferProcessor, fFragmentProcesso
rs.get(), |
| 494 &fSamplerUniforms); | 515 &fSamplerUniforms); |
| 495 } | 516 } |
| 496 | 517 |
| 497 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 518 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 498 | 519 |
| 499 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 520 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
| 500 int numProcs = fProcs.count(); | 521 int numProcs = fProcs.count(); |
| 501 for (int i = 0; i < numProcs; ++i) { | 522 for (int i = 0; i < numProcs; ++i) { |
| 502 delete fProcs[i]; | 523 delete fProcs[i]; |
| 503 } | 524 } |
| 504 } | 525 } |
| OLD | NEW |