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 |