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 #include "gl/GrGLProgram.h" | 9 #include "gl/GrGLProgram.h" |
10 #include "gl/GrGLSLPrettyPrint.h" | 10 #include "gl/GrGLSLPrettyPrint.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 // get the initial color and coverage to feed into the first effect in each
effect chain | 50 // get the initial color and coverage to feed into the first effect in each
effect chain |
51 GrGLSLExpr4 inputColor; | 51 GrGLSLExpr4 inputColor; |
52 GrGLSLExpr1 inputCoverage; | 52 GrGLSLExpr1 inputCoverage; |
53 pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage); | 53 pb->setupUniformColorAndCoverageIfNeeded(&inputColor, &inputCoverage); |
54 | 54 |
55 // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES)
, then we may have | 55 // if we have a vertex shader(we don't only if we are using NVPR or NVPR ES)
, then we may have |
56 // to setup a few more things like builtin vertex attributes | 56 // to setup a few more things like builtin vertex attributes |
57 bool hasVertexShader = !(header.fUseNvpr && | 57 bool hasVertexShader = !(header.fUseNvpr && |
58 gpu->glPathRendering()->texturingMode() == | 58 gpu->glPathRendering()->texturingMode() == |
59 GrGLPathRendering::FixedFunction_TexturingMode); | 59 GrGLPathRendering::FixedFunction_TexturingMode); |
| 60 |
60 if (hasVertexShader) { | 61 if (hasVertexShader) { |
| 62 pb->fVS.setupUniformViewMatrix(); |
61 pb->fVS.setupLocalCoords(); | 63 pb->fVS.setupLocalCoords(); |
62 pb->fVS.transformGLToSkiaCoords(); | |
63 if (header.fEmitsPointSize) { | 64 if (header.fEmitsPointSize) { |
64 pb->fVS.codeAppend("gl_PointSize = 1.0;"); | 65 pb->fVS.codeAppend("gl_PointSize = 1.0;"); |
65 } | 66 } |
66 if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) { | 67 if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) { |
67 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); | 68 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); |
68 } | 69 } |
69 if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { | 70 if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { |
70 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); | 71 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); |
71 } | 72 } |
72 } | 73 } |
73 | 74 |
74 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can | 75 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can |
75 // remove this cast to a vec4. | 76 // remove this cast to a vec4. |
76 GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage); | 77 GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage); |
77 | 78 |
78 pb->emitAndInstallProcs(optState, &inputColor, &inputCoverageVec4); | 79 pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4); |
79 | |
80 if (hasVertexShader) { | |
81 pb->fVS.transformSkiaToGLCoords(); | |
82 } | |
83 | 80 |
84 // write the secondary color output if necessary | 81 // write the secondary color output if necessary |
85 if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType)
{ | 82 if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType)
{ |
86 pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4); | 83 pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4); |
87 } | 84 } |
88 | 85 |
89 pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4); | 86 pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4); |
90 | 87 |
91 return pb->finalize(); | 88 return pb->finalize(); |
92 } | 89 } |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 int co
unt, | 161 int co
unt, |
165 const
char** outName) { | 162 const
char** outName) { |
166 SkASSERT(name && strlen(name)); | 163 SkASSERT(name && strlen(name)); |
167 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); | 164 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); |
168 SkASSERT(0 == (~kVisibilityMask & visibility)); | 165 SkASSERT(0 == (~kVisibilityMask & visibility)); |
169 SkASSERT(0 != visibility); | 166 SkASSERT(0 != visibility); |
170 | 167 |
171 UniformInfo& uni = fUniforms.push_back(); | 168 UniformInfo& uni = fUniforms.push_back(); |
172 uni.fVariable.setType(type); | 169 uni.fVariable.setType(type); |
173 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); | 170 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); |
174 this->nameVariable(uni.fVariable.accessName(), 'u', name); | 171 // TODO this is a bit hacky, lets think of a better way. Basically we need
to be able to use |
| 172 // the uniform view matrix name in the GP, and the GP is immutable so it has
to tell the PB |
| 173 // exactly what name it wants to use for the uniform view matrix. If we pre
fix anythings, then |
| 174 // the names will mismatch. I think the correct solution is to have all GPs
which need the |
| 175 // uniform view matrix, they should upload the view matrix in their setData
along with regular |
| 176 // uniforms. |
| 177 char prefix = 'u'; |
| 178 if ('u' == name[0]) { |
| 179 prefix = '\0'; |
| 180 } |
| 181 this->nameVariable(uni.fVariable.accessName(), prefix, name); |
175 uni.fVariable.setArrayCount(count); | 182 uni.fVariable.setArrayCount(count); |
176 uni.fVisibility = visibility; | 183 uni.fVisibility = visibility; |
177 | 184 |
178 // If it is visible in both the VS and FS, the precision must match. | 185 // If it is visible in both the VS and FS, the precision must match. |
179 // We declare a default FS precision, but not a default VS. So set the var | 186 // We declare a default FS precision, but not a default VS. So set the var |
180 // to use the default FS precision. | 187 // to use the default FS precision. |
181 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { | 188 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { |
182 // the fragment and vertex precisions must match | 189 // the fragment and vertex precisions must match |
183 uni.fVariable.setPrecision(kDefaultFragmentPrecision); | 190 uni.fVariable.setPrecision(kDefaultFragmentPrecision); |
184 } | 191 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 230 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
224 kFloat_GrSLType, | 231 kFloat_GrSLType, |
225 "Coverage", | 232 "Coverage", |
226 &name); | 233 &name); |
227 *inputCoverage = GrGLSLExpr1(name); | 234 *inputCoverage = GrGLSLExpr1(name); |
228 } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { | 235 } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { |
229 *inputCoverage = GrGLSLExpr1(1); | 236 *inputCoverage = GrGLSLExpr1(1); |
230 } | 237 } |
231 } | 238 } |
232 | 239 |
233 void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState, | 240 void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, |
234 GrGLSLExpr4* inputColor, | |
235 GrGLSLExpr4* inputCoverage) { | 241 GrGLSLExpr4* inputCoverage) { |
| 242 // We need to collect all of the transforms to thread them through the GP in
the case of GPs |
| 243 // which use additional shader stages between the VS and the FS. To do this
we emit a dummy |
| 244 // input coverage |
| 245 GrGLSLExpr4 coverageInput = *inputCoverage; |
| 246 if (fOptState.hasGeometryProcessor()) { |
| 247 AutoStageAdvance adv(this); |
| 248 SkString outColorName; |
| 249 this->nameVariable(&outColorName, '\0', "gpOutput"); |
| 250 coverageInput = outColorName; |
| 251 } |
| 252 GrGLSLExpr4 gpOutput = coverageInput; |
| 253 |
| 254 // Emit fragment processors |
236 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); | 255 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); |
237 int numProcs = optState.numFragmentStages(); | 256 int numProcs = fOptState.numFragmentStages(); |
238 this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor); | 257 this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor); |
239 if (optState.hasGeometryProcessor()) { | 258 this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, &covera
geInput); |
240 const GrGeometryProcessor& gp = *optState.getGeometryProcessor(); | 259 |
| 260 // We have to save the existing code stack, and then append it to the fragme
nt shader code |
| 261 // after emiting the GP |
| 262 if (fOptState.hasGeometryProcessor()) { |
| 263 SkString existingCode(fFS.fCode); |
| 264 fFS.fCode.reset(); |
| 265 const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor(); |
241 fVS.emitAttributes(gp); | 266 fVS.emitAttributes(gp); |
242 ProcKeyProvider keyProvider(&fDesc, | 267 ProcKeyProvider keyProvider(&fDesc, |
243 ProcKeyProvider::kGeometry_ProcessorType, | 268 ProcKeyProvider::kGeometry_ProcessorType, |
244 GrGLProgramDescBuilder::kProcessorKeyOffsets
AndLengthOffset); | 269 GrGLProgramDescBuilder::kProcessorKeyOffsets
AndLengthOffset); |
245 GrGLSLExpr4 output; | 270 this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *input
Coverage, &gpOutput); |
246 this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *input
Coverage, &output); | 271 fFS.fCode.append(existingCode); |
247 *inputCoverage = output; | |
248 } | 272 } |
249 this->emitAndInstallFragProcs(optState.numColorStages(), numProcs, inputCov
erage); | 273 *inputCoverage = coverageInput; |
250 } | 274 } |
251 | 275 |
252 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G
rGLSLExpr4* inOut) { | 276 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G
rGLSLExpr4* inOut) { |
253 ProcKeyProvider keyProvider(&fDesc, | 277 ProcKeyProvider keyProvider(&fDesc, |
254 ProcKeyProvider::kFragment_ProcessorType, | 278 ProcKeyProvider::kFragment_ProcessorType, |
255 GrGLProgramDescBuilder::kProcessorKeyOffsetsAndL
engthOffset); | 279 GrGLProgramDescBuilder::kProcessorKeyOffsetsAndL
engthOffset); |
256 for (int e = procOffset; e < numProcs; ++e) { | 280 for (int e = procOffset; e < numProcs; ++e) { |
257 GrGLSLExpr4 output; | 281 GrGLSLExpr4 output; |
258 const GrFragmentStage& stage = fOptState.getFragmentStage(e); | 282 const GrFragmentStage& stage = fOptState.getFragmentStage(e); |
259 this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut,
&output); | 283 this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut,
&output); |
260 *inOut = output; | 284 *inOut = output; |
261 } | 285 } |
262 } | 286 } |
263 | 287 |
264 // TODO Processors cannot output zeros because an empty string is all 1s | 288 // TODO Processors cannot output zeros because an empty string is all 1s |
265 // the fix is to allow effects to take the GrGLSLExpr4 directly | 289 // the fix is to allow effects to take the GrGLSLExpr4 directly |
266 template <class Proc> | 290 template <class Proc> |
267 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc, | 291 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc, |
268 int index, | 292 int index, |
269 const ProcKeyProvider& keyProvider, | 293 const ProcKeyProvider& keyProvider, |
270 const GrGLSLExpr4& input, | 294 const GrGLSLExpr4& input, |
271 GrGLSLExpr4* output) { | 295 GrGLSLExpr4* output) { |
272 // Program builders have a bit of state we need to clear with each effect | 296 // Program builders have a bit of state we need to clear with each effect |
273 AutoStageAdvance adv(this); | 297 AutoStageAdvance adv(this); |
274 | 298 |
275 // create var to hold stage result | 299 // create var to hold stage result. If we already have a valid output name,
just use that |
| 300 // otherwise create a new mangled one. |
276 SkString outColorName; | 301 SkString outColorName; |
277 this->nameVariable(&outColorName, '\0', "output"); | 302 if (output->isValid()) { |
| 303 outColorName = output->c_str(); |
| 304 } else { |
| 305 this->nameVariable(&outColorName, '\0', "output"); |
| 306 } |
278 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); | 307 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); |
279 *output = outColorName; | 308 *output = outColorName; |
280 | 309 |
281 // Enclose custom code in a block to avoid namespace conflicts | 310 // Enclose custom code in a block to avoid namespace conflicts |
282 SkString openBrace; | 311 SkString openBrace; |
283 openBrace.printf("{ // Stage %d\n", fStageIndex); | 312 openBrace.printf("{ // Stage %d\n", fStageIndex); |
284 fFS.codeAppend(openBrace.c_str()); | 313 fFS.codeAppend(openBrace.c_str()); |
285 | 314 |
286 this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(), | 315 this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(), |
287 input.isOnes() ? NULL : input.c_str()); | 316 input.isOnes() ? NULL : input.c_str()); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 uniName, | 396 uniName, |
368 &uniName).toShaderBuilder
Index(); | 397 &uniName).toShaderBuilder
Index(); |
369 | 398 |
370 const char* varyingName = "MatrixCoord"; | 399 const char* varyingName = "MatrixCoord"; |
371 SkString suffixedVaryingName; | 400 SkString suffixedVaryingName; |
372 if (0 != t) { | 401 if (0 != t) { |
373 suffixedVaryingName.append(varyingName); | 402 suffixedVaryingName.append(varyingName); |
374 suffixedVaryingName.appendf("_%i", t); | 403 suffixedVaryingName.appendf("_%i", t); |
375 varyingName = suffixedVaryingName.c_str(); | 404 varyingName = suffixedVaryingName.c_str(); |
376 } | 405 } |
| 406 const char* coords = kPosition_GrCoordSet == effect->coordTransform(t).s
ourceCoords() ? |
| 407 fVS.positionAttribute().c_s
tr() : |
| 408 fVS.localCoordsAttribute().
c_str(); |
377 GrGLVertToFrag v(varyingType); | 409 GrGLVertToFrag v(varyingType); |
378 this->addVarying(varyingName, &v); | 410 this->addCoordVarying(varyingName, &v, uniName, coords); |
379 | 411 |
380 const GrGLShaderVar& coords = | |
381 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords()
? | |
382 fVS.positionAttribute() : | |
383 fVS.localCoordsAttribute(); | |
384 | |
385 // varying = matrix * coords (logically) | |
386 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingTyp
e); | 412 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingTyp
e); |
387 if (kVec2f_GrSLType == varyingType) { | |
388 fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;", | |
389 v.vsOut(), uniName, coords.c_str()); | |
390 } else { | |
391 fVS.codeAppendf("%s = %s * vec3(%s, 1);", | |
392 v.vsOut(), uniName, coords.c_str()); | |
393 } | |
394 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, | 413 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, |
395 (SkString(v.fsIn()), varyingType)); | 414 (SkString(v.fsIn()), varyingType)); |
396 } | 415 } |
397 } | 416 } |
398 | 417 |
399 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, | 418 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, |
400 GrGLProcessor::TextureSamplerArray* outSam
plers, | 419 GrGLProcessor::TextureSamplerArray* outSam
plers, |
401 GrGLInstalledProc* ip) { | 420 GrGLInstalledProc* ip) { |
402 int numTextures = processor.numTextures(); | 421 int numTextures = processor.numTextures(); |
403 ip->fSamplers.push_back_n(numTextures); | 422 ip->fSamplers.push_back_n(numTextures); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 } | 535 } |
517 | 536 |
518 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 537 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
519 | 538 |
520 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 539 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
521 int numProcs = fProcs.count(); | 540 int numProcs = fProcs.count(); |
522 for (int e = 0; e < numProcs; ++e) { | 541 for (int e = 0; e < numProcs; ++e) { |
523 SkDELETE(fProcs[e]); | 542 SkDELETE(fProcs[e]); |
524 } | 543 } |
525 } | 544 } |
OLD | NEW |