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) { |
61 pb->fVS.setupLocalCoords(); | 62 pb->fVS.setupUniformViewMatrix(); |
62 pb->fVS.transformGLToSkiaCoords(); | 63 pb->fVS.setupPositionAndLocalCoords(); |
| 64 |
63 if (header.fEmitsPointSize) { | 65 if (header.fEmitsPointSize) { |
64 pb->fVS.codeAppend("gl_PointSize = 1.0;"); | 66 pb->fVS.codeAppend("gl_PointSize = 1.0;"); |
65 } | 67 } |
66 if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) { | 68 if (GrProgramDesc::kAttribute_ColorInput == header.fColorInput) { |
67 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); | 69 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); |
68 } | 70 } |
69 if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { | 71 if (GrProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { |
70 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); | 72 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); |
71 } | 73 } |
72 } | 74 } |
73 | 75 |
74 // TODO: Once all stages can handle taking a float or vec4 and correctly han
dling them we can | 76 // 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. | 77 // remove this cast to a vec4. |
76 GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage); | 78 GrGLSLExpr4 inputCoverageVec4 = GrGLSLExpr4::VectorCast(inputCoverage); |
77 | 79 |
78 pb->emitAndInstallProcs(optState, &inputColor, &inputCoverageVec4); | 80 pb->emitAndInstallProcs(&inputColor, &inputCoverageVec4); |
79 | 81 |
80 if (hasVertexShader) { | 82 if (hasVertexShader) { |
81 pb->fVS.transformSkiaToGLCoords(); | 83 pb->fVS.transformToNormalizedDeviceSpace(); |
82 } | 84 } |
83 | 85 |
84 // write the secondary color output if necessary | 86 // write the secondary color output if necessary |
85 if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType)
{ | 87 if (GrProgramDesc::kNone_SecondaryOutputType != header.fSecondaryOutputType)
{ |
86 pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4); | 88 pb->fFS.enableSecondaryOutput(inputColor, inputCoverageVec4); |
87 } | 89 } |
88 | 90 |
89 pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4); | 91 pb->fFS.combineColorAndCoverage(inputColor, inputCoverageVec4); |
90 | 92 |
91 return pb->finalize(); | 93 return pb->finalize(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 int co
unt, | 166 int co
unt, |
165 const
char** outName) { | 167 const
char** outName) { |
166 SkASSERT(name && strlen(name)); | 168 SkASSERT(name && strlen(name)); |
167 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); | 169 SkDEBUGCODE(static const uint32_t kVisibilityMask = kVertex_Visibility | kFr
agment_Visibility); |
168 SkASSERT(0 == (~kVisibilityMask & visibility)); | 170 SkASSERT(0 == (~kVisibilityMask & visibility)); |
169 SkASSERT(0 != visibility); | 171 SkASSERT(0 != visibility); |
170 | 172 |
171 UniformInfo& uni = fUniforms.push_back(); | 173 UniformInfo& uni = fUniforms.push_back(); |
172 uni.fVariable.setType(type); | 174 uni.fVariable.setType(type); |
173 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); | 175 uni.fVariable.setTypeModifier(GrGLShaderVar::kUniform_TypeModifier); |
174 this->nameVariable(uni.fVariable.accessName(), 'u', name); | 176 // TODO this is a bit hacky, lets think of a better way. Basically we need
to be able to use |
| 177 // the uniform view matrix name in the GP, and the GP is immutable so it has
to tell the PB |
| 178 // exactly what name it wants to use for the uniform view matrix. If we pre
fix anythings, then |
| 179 // the names will mismatch. I think the correct solution is to have all GPs
which need the |
| 180 // uniform view matrix, they should upload the view matrix in their setData
along with regular |
| 181 // uniforms. |
| 182 char prefix = 'u'; |
| 183 if ('u' == name[0]) { |
| 184 prefix = '\0'; |
| 185 } |
| 186 this->nameVariable(uni.fVariable.accessName(), prefix, name); |
175 uni.fVariable.setArrayCount(count); | 187 uni.fVariable.setArrayCount(count); |
176 uni.fVisibility = visibility; | 188 uni.fVisibility = visibility; |
177 | 189 |
178 // If it is visible in both the VS and FS, the precision must match. | 190 // 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 | 191 // We declare a default FS precision, but not a default VS. So set the var |
180 // to use the default FS precision. | 192 // to use the default FS precision. |
181 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { | 193 if ((kVertex_Visibility | kFragment_Visibility) == visibility) { |
182 // the fragment and vertex precisions must match | 194 // the fragment and vertex precisions must match |
183 uni.fVariable.setPrecision(kDefaultFragmentPrecision); | 195 uni.fVariable.setPrecision(kDefaultFragmentPrecision); |
184 } | 196 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 235 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
224 kFloat_GrSLType, | 236 kFloat_GrSLType, |
225 "Coverage", | 237 "Coverage", |
226 &name); | 238 &name); |
227 *inputCoverage = GrGLSLExpr1(name); | 239 *inputCoverage = GrGLSLExpr1(name); |
228 } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { | 240 } else if (GrProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { |
229 *inputCoverage = GrGLSLExpr1(1); | 241 *inputCoverage = GrGLSLExpr1(1); |
230 } | 242 } |
231 } | 243 } |
232 | 244 |
233 void GrGLProgramBuilder::emitAndInstallProcs(const GrOptDrawState& optState, | 245 void GrGLProgramBuilder::emitAndInstallProcs(GrGLSLExpr4* inputColor, |
234 GrGLSLExpr4* inputColor, | |
235 GrGLSLExpr4* inputCoverage) { | 246 GrGLSLExpr4* inputCoverage) { |
236 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); | 247 fFragmentProcessors.reset(SkNEW(GrGLInstalledFragProcs)); |
237 int numProcs = optState.numFragmentStages(); | 248 int numProcs = fOptState.numFragmentStages(); |
238 this->emitAndInstallFragProcs(0, optState.numColorStages(), inputColor); | 249 this->emitAndInstallFragProcs(0, fOptState.numColorStages(), inputColor); |
239 if (optState.hasGeometryProcessor()) { | 250 if (fOptState.hasGeometryProcessor()) { |
240 const GrGeometryProcessor& gp = *optState.getGeometryProcessor(); | 251 const GrGeometryProcessor& gp = *fOptState.getGeometryProcessor(); |
241 fVS.emitAttributes(gp); | 252 fVS.emitAttributes(gp); |
242 ProcKeyProvider keyProvider(&fDesc, | 253 ProcKeyProvider keyProvider(&fDesc, |
243 ProcKeyProvider::kGeometry_ProcessorType, | 254 ProcKeyProvider::kGeometry_ProcessorType, |
244 GrGLProgramDescBuilder::kProcessorKeyOffsets
AndLengthOffset); | 255 GrGLProgramDescBuilder::kProcessorKeyOffsets
AndLengthOffset); |
245 GrGLSLExpr4 output; | 256 GrGLSLExpr4 output; |
246 this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *input
Coverage, &output); | 257 this->emitAndInstallProc<GrGeometryProcessor>(gp, 0, keyProvider, *input
Coverage, &output); |
247 *inputCoverage = output; | 258 *inputCoverage = output; |
248 } | 259 } |
249 this->emitAndInstallFragProcs(optState.numColorStages(), numProcs, inputCov
erage); | 260 this->emitAndInstallFragProcs(fOptState.numColorStages(), numProcs, inputCo
verage); |
250 } | 261 } |
251 | 262 |
252 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G
rGLSLExpr4* inOut) { | 263 void GrGLProgramBuilder::emitAndInstallFragProcs(int procOffset, int numProcs, G
rGLSLExpr4* inOut) { |
253 ProcKeyProvider keyProvider(&fDesc, | 264 ProcKeyProvider keyProvider(&fDesc, |
254 ProcKeyProvider::kFragment_ProcessorType, | 265 ProcKeyProvider::kFragment_ProcessorType, |
255 GrGLProgramDescBuilder::kProcessorKeyOffsetsAndL
engthOffset); | 266 GrGLProgramDescBuilder::kProcessorKeyOffsetsAndL
engthOffset); |
256 for (int e = procOffset; e < numProcs; ++e) { | 267 for (int e = procOffset; e < numProcs; ++e) { |
257 GrGLSLExpr4 output; | 268 GrGLSLExpr4 output; |
258 const GrFragmentStage& stage = fOptState.getFragmentStage(e); | 269 const GrFragmentStage& stage = fOptState.getFragmentStage(e); |
259 this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut,
&output); | 270 this->emitAndInstallProc<GrFragmentStage>(stage, e, keyProvider, *inOut,
&output); |
260 *inOut = output; | 271 *inOut = output; |
261 } | 272 } |
262 } | 273 } |
263 | 274 |
264 // TODO Processors cannot output zeros because an empty string is all 1s | 275 // TODO Processors cannot output zeros because an empty string is all 1s |
265 // the fix is to allow effects to take the GrGLSLExpr4 directly | 276 // the fix is to allow effects to take the GrGLSLExpr4 directly |
266 template <class Proc> | 277 template <class Proc> |
267 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc, | 278 void GrGLProgramBuilder::emitAndInstallProc(const Proc& proc, |
268 int index, | 279 int index, |
269 const ProcKeyProvider& keyProvider, | 280 const ProcKeyProvider& keyProvider, |
270 const GrGLSLExpr4& input, | 281 const GrGLSLExpr4& input, |
271 GrGLSLExpr4* output) { | 282 GrGLSLExpr4* output) { |
272 // Program builders have a bit of state we need to clear with each effect | 283 // Program builders have a bit of state we need to clear with each effect |
273 AutoStageAdvance adv(this); | 284 AutoStageAdvance adv(this); |
274 | 285 |
275 // create var to hold stage result | 286 // create var to hold stage result. If we already have a valid output name,
just use that |
| 287 // otherwise create a new mangled one. |
276 SkString outColorName; | 288 SkString outColorName; |
277 this->nameVariable(&outColorName, '\0', "output"); | 289 if (output->isValid()) { |
| 290 outColorName = output->c_str(); |
| 291 } else { |
| 292 this->nameVariable(&outColorName, '\0', "output"); |
| 293 } |
278 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); | 294 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); |
279 *output = outColorName; | 295 *output = outColorName; |
280 | 296 |
281 // Enclose custom code in a block to avoid namespace conflicts | 297 // Enclose custom code in a block to avoid namespace conflicts |
282 SkString openBrace; | 298 SkString openBrace; |
283 openBrace.printf("{ // Stage %d\n", fStageIndex); | 299 openBrace.printf("{ // Stage %d\n", fStageIndex); |
284 fFS.codeAppend(openBrace.c_str()); | 300 fFS.codeAppend(openBrace.c_str()); |
285 | 301 |
286 this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(), | 302 this->emitAndInstallProc(proc, keyProvider.get(index), output->c_str(), |
287 input.isOnes() ? NULL : input.c_str()); | 303 input.isOnes() ? NULL : input.c_str()); |
(...skipping 20 matching lines...) Expand all Loading... |
308 ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers); | 324 ifp->fGLProc->emitCode(this, fp, key, outColor, inColor, coords, samplers); |
309 | 325 |
310 // We have to check that effects and the code they emit are consistent, ie i
f an effect | 326 // We have to check that effects and the code they emit are consistent, ie i
f an effect |
311 // asks for dst color, then the emit code needs to follow suit | 327 // asks for dst color, then the emit code needs to follow suit |
312 verify(fp); | 328 verify(fp); |
313 fFragmentProcessors->fProcs.push_back(ifp); | 329 fFragmentProcessors->fProcs.push_back(ifp); |
314 } | 330 } |
315 | 331 |
316 void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp, | 332 void GrGLProgramBuilder::emitAndInstallProc(const GrGeometryProcessor& gp, |
317 const GrProcessorKey& key, | 333 const GrProcessorKey& key, |
318 const char* outColor, | 334 const char* outCoverage, |
319 const char* inColor) { | 335 const char* inCoverage) { |
320 SkASSERT(!fGeometryProcessor); | 336 SkASSERT(!fGeometryProcessor); |
321 fGeometryProcessor = SkNEW(GrGLInstalledGeoProc); | 337 fGeometryProcessor = SkNEW(GrGLInstalledGeoProc); |
322 | 338 |
323 fGeometryProcessor->fGLProc.reset(gp.getFactory().createGLInstance(gp)); | 339 fGeometryProcessor->fGLProc.reset(gp.getFactory().createGLInstance(gp)); |
324 | 340 |
325 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures()); | 341 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(gp.numTextures()); |
326 this->emitSamplers(gp, &samplers, fGeometryProcessor); | 342 this->emitSamplers(gp, &samplers, fGeometryProcessor); |
327 | 343 |
328 GrGLGeometryProcessor::EmitArgs args(this, gp, key, outColor, inColor, sampl
ers); | 344 GrGLGeometryProcessor::EmitArgs args(this, gp, key, outCoverage, inCoverage,
samplers); |
329 fGeometryProcessor->fGLProc->emitCode(args); | 345 fGeometryProcessor->fGLProc->emitCode(args); |
330 | 346 |
331 // We have to check that effects and the code they emit are consistent, ie i
f an effect | 347 // We have to check that effects and the code they emit are consistent, ie i
f an effect |
332 // asks for dst color, then the emit code needs to follow suit | 348 // asks for dst color, then the emit code needs to follow suit |
333 verify(gp); | 349 verify(gp); |
334 } | 350 } |
335 | 351 |
336 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) { | 352 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) { |
337 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); | 353 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); |
338 } | 354 } |
(...skipping 28 matching lines...) Expand all Loading... |
367 uniName, | 383 uniName, |
368 &uniName).toShaderBuilder
Index(); | 384 &uniName).toShaderBuilder
Index(); |
369 | 385 |
370 const char* varyingName = "MatrixCoord"; | 386 const char* varyingName = "MatrixCoord"; |
371 SkString suffixedVaryingName; | 387 SkString suffixedVaryingName; |
372 if (0 != t) { | 388 if (0 != t) { |
373 suffixedVaryingName.append(varyingName); | 389 suffixedVaryingName.append(varyingName); |
374 suffixedVaryingName.appendf("_%i", t); | 390 suffixedVaryingName.appendf("_%i", t); |
375 varyingName = suffixedVaryingName.c_str(); | 391 varyingName = suffixedVaryingName.c_str(); |
376 } | 392 } |
| 393 const char* coords = kPosition_GrCoordSet == effect->coordTransform(t).s
ourceCoords() ? |
| 394 fVS.positionAttribute().c_s
tr() : |
| 395 fVS.localCoordsAttribute().
c_str(); |
377 GrGLVertToFrag v(varyingType); | 396 GrGLVertToFrag v(varyingType); |
378 this->addVarying(varyingName, &v); | 397 this->addCoordVarying(varyingName, &v, uniName, coords); |
379 | 398 |
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); | 399 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, | 400 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, |
395 (SkString(v.fsIn()), varyingType)); | 401 (SkString(v.fsIn()), varyingType)); |
396 } | 402 } |
397 } | 403 } |
398 | 404 |
399 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, | 405 void GrGLProgramBuilder::emitSamplers(const GrProcessor& processor, |
400 GrGLProcessor::TextureSamplerArray* outSam
plers, | 406 GrGLProcessor::TextureSamplerArray* outSam
plers, |
401 GrGLInstalledProc* ip) { | 407 GrGLInstalledProc* ip) { |
402 int numTextures = processor.numTextures(); | 408 int numTextures = processor.numTextures(); |
403 ip->fSamplers.push_back_n(numTextures); | 409 ip->fSamplers.push_back_n(numTextures); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 } | 522 } |
517 | 523 |
518 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 524 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
519 | 525 |
520 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { | 526 GrGLInstalledFragProcs::~GrGLInstalledFragProcs() { |
521 int numProcs = fProcs.count(); | 527 int numProcs = fProcs.count(); |
522 for (int e = 0; e < numProcs; ++e) { | 528 for (int e = 0; e < numProcs; ++e) { |
523 SkDELETE(fProcs[e]); | 529 SkDELETE(fProcs[e]); |
524 } | 530 } |
525 } | 531 } |
OLD | NEW |