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/GrGLGeometryProcessor.h" | 9 #include "gl/GrGLGeometryProcessor.h" |
10 #include "gl/GrGLProgram.h" | 10 #include "gl/GrGLProgram.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) | 22 #define GL_CALL(X) GR_GL_CALL(this->gpu()->glInterface(), X) |
23 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) | 23 #define GL_CALL_RET(R, X) GR_GL_CALL_RET(this->gpu()->glInterface(), R, X) |
24 | 24 |
25 // ES2 FS only guarantees mediump and lowp support | 25 // ES2 FS only guarantees mediump and lowp support |
26 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
:kMedium_Precision; | 26 static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar:
:kMedium_Precision; |
27 | 27 |
28 ////////////////////////////////////////////////////////////////////////////// | 28 ////////////////////////////////////////////////////////////////////////////// |
29 | 29 |
30 const int GrGLProgramBuilder::kVarsPerBlock = 8; | 30 const int GrGLProgramBuilder::kVarsPerBlock = 8; |
31 | 31 |
| 32 // Below are some helper classes which help keep the create and emit pipeline ge
neral |
| 33 template <class Derived> |
| 34 struct FragmentStageClassMap { |
| 35 static const GrFragmentProcessor* GetProcessor(const GrOptDrawState& opt, in
t index) { |
| 36 SkASSERT(Derived::GetStage(opt, index)->getProcessor()); |
| 37 return Derived::GetStage(opt, index)->getProcessor(); |
| 38 } |
| 39 typedef GrFragmentProcessor Processor; |
| 40 typedef GrFragmentStage ProcessorStaged; |
| 41 typedef GrGLFragmentProcessor GLProcessor; |
| 42 }; |
| 43 |
| 44 struct ColorStageClassMap : public FragmentStageClassMap<ColorStageClassMap> { |
| 45 static int GetCount(const GrOptDrawState& opt) { return opt.numColorStages()
; } |
| 46 static const GrFragmentStage* GetStage(const GrOptDrawState& opt, int index)
{ |
| 47 return &opt.getColorStage(index); |
| 48 } |
| 49 }; |
| 50 |
| 51 struct CoverageStageClassMap : public FragmentStageClassMap<CoverageStageClassMa
p> { |
| 52 static int GetCount(const GrOptDrawState& opt) { return opt.numCoverageStage
s(); } |
| 53 static const GrFragmentStage* GetStage(const GrOptDrawState& opt, int index)
{ |
| 54 return &opt.getCoverageStage(index); |
| 55 } |
| 56 }; |
| 57 |
| 58 struct GeometryProcessorClassMap { |
| 59 static int GetCount(const GrOptDrawState& opt) { return 1; } |
| 60 static const GrGeometryProcessor* GetStage(const GrOptDrawState& opt, int in
dex) { |
| 61 SkASSERT(0 == index && opt.hasGeometryProcessor()); |
| 62 return opt.getGeometryProcessor(); |
| 63 } |
| 64 static const GrGeometryProcessor* GetProcessor(const GrOptDrawState& opt, in
t index) { |
| 65 return GetStage(opt, index); |
| 66 } |
| 67 typedef GrGeometryProcessor Processor; |
| 68 typedef GrGeometryProcessor ProcessorStaged; |
| 69 typedef GrGLGeometryProcessor GLProcessor; |
| 70 }; |
| 71 |
| 72 ////////////////////////////////////////////////////////////////////////////////
////////////////// |
| 73 |
32 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, | 74 GrGLProgram* GrGLProgramBuilder::CreateProgram(const GrOptDrawState& optState, |
33 const GrGLProgramDesc& desc, | 75 const GrGLProgramDesc& desc, |
34 GrGpu::DrawType drawType, | 76 GrGpu::DrawType drawType, |
35 const GrGeometryStage* geometryPr
ocessor, | |
36 const GrFragmentStage* colorStage
s[], | |
37 const GrFragmentStage* coverageSt
ages[], | |
38 GrGpuGL* gpu) { | 77 GrGpuGL* gpu) { |
39 // create a builder. This will be handed off to effects so they can use it
to add | 78 // create a builder. This will be handed off to effects so they can use it
to add |
40 // uniforms, varyings, textures, etc | 79 // uniforms, varyings, textures, etc |
41 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc, | 80 SkAutoTDelete<GrGLProgramBuilder> builder(CreateProgramBuilder(desc, |
42 optState, | 81 optState, |
43 drawType, | 82 drawType, |
44 SkToBool(geom
etryProcessor), | 83 optState.hasG
eometryProcessor(), |
45 gpu)); | 84 gpu)); |
46 | 85 |
47 GrGLProgramBuilder* pb = builder.get(); | 86 GrGLProgramBuilder* pb = builder.get(); |
48 const GrGLProgramDesc::KeyHeader& header = pb->header(); | 87 const GrGLProgramDesc::KeyHeader& header = pb->header(); |
49 | 88 |
50 // emit code to read the dst copy texture, if necessary | 89 // emit code to read the dst copy texture, if necessary |
51 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey | 90 if (GrGLFragmentShaderBuilder::kNoDstRead_DstReadKey != header.fDstReadKey |
52 && !gpu->glCaps().fbFetchSupport()) { | 91 && !gpu->glCaps().fbFetchSupport()) { |
53 pb->fFS.emitCodeToReadDstTexture(); | 92 pb->fFS.emitCodeToReadDstTexture(); |
54 } | 93 } |
(...skipping 12 matching lines...) Expand all Loading... |
67 pb->fVS.codeAppend("gl_PointSize = 1.0;"); | 106 pb->fVS.codeAppend("gl_PointSize = 1.0;"); |
68 } | 107 } |
69 if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) { | 108 if (GrGLProgramDesc::kAttribute_ColorInput == header.fColorInput) { |
70 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); | 109 pb->fVS.setupBuiltinVertexAttribute("Color", &inputColor); |
71 } | 110 } |
72 if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { | 111 if (GrGLProgramDesc::kAttribute_ColorInput == header.fCoverageInput) { |
73 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); | 112 pb->fVS.setupBuiltinVertexAttribute("Coverage", &inputCoverage); |
74 } | 113 } |
75 } | 114 } |
76 | 115 |
77 pb->createAndEmitProcessors(geometryProcessor, colorStages, coverageStages,
&inputColor, | 116 bool useLocalCoords = pb->fVS.hasExplicitLocalCoords(); |
78 &inputCoverage); | 117 pb->createAndEmitProcessors<ColorStageClassMap>(EffectKeyProvider::kColor_Ef
fectType, |
| 118 useLocalCoords, |
| 119 &pb->fColorEffects, |
| 120 &inputColor); |
| 121 if (optState.hasGeometryProcessor()) { |
| 122 pb->fVS.emitAttributes(*optState.getGeometryProcessor()); |
| 123 pb->createAndEmitProcessors<GeometryProcessorClassMap>( |
| 124 EffectKeyProvider::kGeometryProcessor_EffectType, |
| 125 false, |
| 126 &pb->fGeometryProcessor, |
| 127 &inputCoverage); |
| 128 } |
| 129 pb->createAndEmitProcessors<CoverageStageClassMap>(EffectKeyProvider::kCover
age_EffectType, |
| 130 useLocalCoords, |
| 131 &pb->fCoverageEffects, |
| 132 &inputCoverage); |
79 | 133 |
80 if (hasVertexShader) { | 134 if (hasVertexShader) { |
81 pb->fVS.transformSkiaToGLCoords(); | 135 pb->fVS.transformSkiaToGLCoords(); |
82 } | 136 } |
83 | 137 |
84 // write the secondary color output if necessary | 138 // write the secondary color output if necessary |
85 if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType
) { | 139 if (GrOptDrawState::kNone_SecondaryOutputType != header.fSecondaryOutputType
) { |
86 pb->fFS.enableSecondaryOutput(inputColor, inputCoverage); | 140 pb->fFS.enableSecondaryOutput(inputColor, inputCoverage); |
87 } | 141 } |
88 | 142 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 272 this->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
219 kVec4f_GrSLType, | 273 kVec4f_GrSLType, |
220 "Coverage", | 274 "Coverage", |
221 &name); | 275 &name); |
222 *inputCoverage = GrGLSLExpr4(name); | 276 *inputCoverage = GrGLSLExpr4(name); |
223 } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { | 277 } else if (GrGLProgramDesc::kAllOnes_ColorInput == header.fCoverageInput) { |
224 *inputCoverage = GrGLSLExpr4(1); | 278 *inputCoverage = GrGLSLExpr4(1); |
225 } | 279 } |
226 } | 280 } |
227 | 281 |
228 void GrGLProgramBuilder::createAndEmitProcessors(const GrGeometryStage* geometry
Processor, | 282 template <class ClassMap> |
229 const GrFragmentStage* colorSta
ges[], | 283 void GrGLProgramBuilder::createAndEmitProcessors(const EffectKeyProvider::Effect
Type type, |
230 const GrFragmentStage* coverage
Stages[], | 284 bool useLocalCoords, |
231 GrGLSLExpr4* inputColor, | 285 SkAutoTUnref<GrGLInstalledProce
ssors>* installProc, |
232 GrGLSLExpr4* inputCoverage) { | 286 GrGLSLExpr4* fsInOutColor) { |
233 bool useLocalCoords = fVS.hasExplicitLocalCoords(); | 287 // setup key provider and install point |
| 288 EffectKeyProvider keyProvider(&fDesc, type); |
| 289 int numProcs = ClassMap::GetCount(fOptState); |
| 290 GrGLInstalledProcessors* ip = SkNEW_ARGS(GrGLInstalledProcessors, (numProcs,
useLocalCoords)); |
234 | 291 |
235 EffectKeyProvider colorKeyProvider(&fDesc, EffectKeyProvider::kColor_EffectT
ype); | |
236 int numColorEffects = fDesc.numColorEffects(); | |
237 GrGLInstalledProcessors* ip = SkNEW_ARGS(GrGLInstalledProcessors, (numColorE
ffects, | |
238 useLocalC
oords)); | |
239 this->createAndEmitProcessors<GrFragmentStage>(colorStages, numColorEffects,
colorKeyProvider, | |
240 inputColor, ip); | |
241 fColorEffects.reset(ip); | |
242 | |
243 if (geometryProcessor) { | |
244 fVS.emitAttributes(*geometryProcessor->getProcessor()); | |
245 EffectKeyProvider gpKeyProvider(&fDesc, EffectKeyProvider::kGeometryProc
essor_EffectType); | |
246 ip = SkNEW_ARGS(GrGLInstalledProcessors, (1, useLocalCoords)); | |
247 this->createAndEmitProcessors<GrGeometryStage>(&geometryProcessor, 1, gp
KeyProvider, | |
248 inputCoverage, ip); | |
249 fGeometryProcessor.reset(ip); | |
250 } | |
251 | |
252 EffectKeyProvider coverageKeyProvider(&fDesc, EffectKeyProvider::kCoverage_E
ffectType); | |
253 int numCoverageEffects = fDesc.numCoverageEffects(); | |
254 ip = SkNEW_ARGS(GrGLInstalledProcessors, (numCoverageEffects, useLocalCoords
)); | |
255 this->createAndEmitProcessors<GrFragmentStage>(coverageStages, numCoverageEf
fects, | |
256 coverageKeyProvider, inputCov
erage, ip); | |
257 fCoverageEffects.reset(ip); | |
258 } | |
259 | |
260 template <class ProcessorStage> | |
261 void GrGLProgramBuilder::createAndEmitProcessors(const ProcessorStage* processSt
ages[], | |
262 int effectCnt, | |
263 const EffectKeyProvider& keyPro
vider, | |
264 GrGLSLExpr4* fsInOutColor, | |
265 GrGLInstalledProcessors* instal
ledProcessors) { | |
266 bool effectEmitted = false; | 292 bool effectEmitted = false; |
267 | 293 |
268 GrGLSLExpr4 inColor = *fsInOutColor; | 294 GrGLSLExpr4 inColor = *fsInOutColor; |
269 GrGLSLExpr4 outColor; | 295 GrGLSLExpr4 outColor; |
270 | 296 |
271 for (int e = 0; e < effectCnt; ++e) { | 297 for (int e = 0; e < numProcs; ++e) { |
272 // Program builders have a bit of state we need to clear with each effec
t | 298 // Program builders have a bit of state we need to clear with each effec
t |
273 AutoStageAdvance adv(this); | 299 AutoStageAdvance adv(this); |
274 const ProcessorStage& stage = *processStages[e]; | |
275 SkASSERT(stage.getProcessor()); | |
276 | 300 |
277 if (inColor.isZeros()) { | 301 if (inColor.isZeros()) { |
278 SkString inColorName; | 302 SkString inColorName; |
279 | 303 |
280 // Effects have no way to communicate zeros, they treat an empty str
ing as ones. | 304 // Effects have no way to communicate zeros, they treat an empty str
ing as ones. |
281 this->nameVariable(&inColorName, '\0', "input"); | 305 this->nameVariable(&inColorName, '\0', "input"); |
282 fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str(
)); | 306 fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str(
)); |
283 inColor = inColorName; | 307 inColor = inColorName; |
284 } | 308 } |
285 | 309 |
286 // create var to hold stage result | 310 // create var to hold stage result |
287 SkString outColorName; | 311 SkString outColorName; |
288 this->nameVariable(&outColorName, '\0', "output"); | 312 this->nameVariable(&outColorName, '\0', "output"); |
289 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); | 313 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); |
290 outColor = outColorName; | 314 outColor = outColorName; |
291 | 315 |
292 SkASSERT(installedProcessors); | 316 SkASSERT(ip); |
293 const typename ProcessorStage::Processor& processor = *stage.getProcesso
r(); | 317 const typename ClassMap::Processor& processor = *ClassMap::GetProcessor(
fOptState, e); |
294 SkSTArray<2, GrGLProcessor::TransformedCoords> coords(processor.numTrans
forms()); | |
295 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(processor.numTextur
es()); | |
296 | 318 |
297 this->emitTransforms(stage, &coords, installedProcessors); | 319 typename ClassMap::GLProcessor* glProc = processor.getFactory().createGL
Instance(processor); |
298 this->emitSamplers(processor, &samplers, installedProcessors); | 320 ip->addEffect(glProc); |
299 | |
300 typename ProcessorStage::GLProcessor* glEffect = | |
301 processor.getFactory().createGLInstance(processor); | |
302 installedProcessors->addEffect(glEffect); | |
303 | 321 |
304 // Enclose custom code in a block to avoid namespace conflicts | 322 // Enclose custom code in a block to avoid namespace conflicts |
305 SkString openBrace; | 323 SkString openBrace; |
306 openBrace.printf("{ // Stage %d: %s\n", fStageIndex, glEffect->name()); | 324 openBrace.printf("{ // Stage %d: %s\n", fStageIndex, glProc->name()); |
307 fFS.codeAppend(openBrace.c_str()); | 325 fFS.codeAppend(openBrace.c_str()); |
308 fVS.codeAppend(openBrace.c_str()); | 326 fVS.codeAppend(openBrace.c_str()); |
309 | 327 |
310 glEffect->emitCode(this, processor, keyProvider.get(e), outColor.c_str()
, | 328 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(processor.numTextur
es()); |
311 inColor.isOnes() ? NULL : inColor.c_str(), coords, sa
mplers); | 329 this->emitSamplers(processor, &samplers, ip); |
| 330 |
| 331 this->emit(*ClassMap::GetStage(fOptState, e), keyProvider.get(e), outCol
or.c_str(), |
| 332 inColor.isOnes() ? NULL : inColor.c_str(), samplers, ip, glPr
oc); |
| 333 |
| 334 fFS.codeAppend("}"); |
| 335 fVS.codeAppend("}"); |
312 | 336 |
313 // We have to check that effects and the code they emit are consistent,
ie if an effect | 337 // We have to check that effects and the code they emit are consistent,
ie if an effect |
314 // asks for dst color, then the emit code needs to follow suit | 338 // asks for dst color, then the emit code needs to follow suit |
315 verify(processor); | 339 verify(processor); |
316 fFS.codeAppend("}"); | |
317 fVS.codeAppend("}"); | |
318 | 340 |
319 inColor = outColor; | 341 inColor = outColor; |
320 effectEmitted = true; | 342 effectEmitted = true; |
321 } | 343 } |
322 | 344 |
323 if (effectEmitted) { | 345 if (effectEmitted) { |
324 *fsInOutColor = outColor; | 346 *fsInOutColor = outColor; |
325 } | 347 } |
| 348 |
| 349 // write to output array |
| 350 SkASSERT(installProc); |
| 351 installProc->reset(ip); |
| 352 } |
| 353 |
| 354 void GrGLProgramBuilder::emit(const GrFragmentStage& fs, |
| 355 const GrProcessorKey& key, |
| 356 const char* outColor, |
| 357 const char* inColor, |
| 358 const GrGLProcessor::TextureSamplerArray& samplers
, |
| 359 GrGLInstalledProcessors* ip, |
| 360 GrGLFragmentProcessor* glProc) { |
| 361 // Fragment processors can have coord transforms |
| 362 const GrFragmentProcessor* fp = fs.getProcessor(); |
| 363 SkSTArray<2, GrGLProcessor::TransformedCoords> coords(fp->numTransforms()); |
| 364 this->emitTransforms(fs, &coords, ip); |
| 365 |
| 366 glProc->emitCode(this, *fp, key, outColor, inColor, coords, samplers); |
| 367 } |
| 368 |
| 369 void GrGLProgramBuilder::emit(const GrGeometryProcessor& gp, |
| 370 const GrProcessorKey& key, |
| 371 const char* outColor, |
| 372 const char* inColor, |
| 373 const GrGLProcessor::TextureSamplerArray& samplers
, |
| 374 GrGLInstalledProcessors* ip, |
| 375 GrGLGeometryProcessor* glProc) { |
| 376 // TODO remove coords from emit code signature, probably best to use a struc
t here so these |
| 377 // updates are less painful |
| 378 SkSTArray<2, GrGLProcessor::TransformedCoords> coords; |
| 379 glProc->emitCode(this, gp, key, outColor, inColor, coords, samplers); |
326 } | 380 } |
327 | 381 |
328 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) { | 382 void GrGLProgramBuilder::verify(const GrGeometryProcessor& gp) { |
329 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); | 383 SkASSERT(fFS.hasReadFragmentPosition() == gp.willReadFragmentPosition()); |
330 } | 384 } |
331 | 385 |
332 void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) { | 386 void GrGLProgramBuilder::verify(const GrFragmentProcessor& fp) { |
333 SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition()); | 387 SkASSERT(fFS.hasReadFragmentPosition() == fp.willReadFragmentPosition()); |
334 SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor()); | 388 SkASSERT(fFS.hasReadDstColor() == fp.willReadDstColor()); |
335 } | 389 } |
336 | 390 |
337 void GrGLProgramBuilder::emitTransforms(const GrProcessorStage& effectStage, | 391 void GrGLProgramBuilder::emitTransforms(const GrFragmentStage& effectStage, |
338 GrGLProcessor::TransformedCoordsArray* o
utCoords, | 392 GrGLProcessor::TransformedCoordsArray* o
utCoords, |
339 GrGLInstalledProcessors* installedProces
sors) { | 393 GrGLInstalledProcessors* installedProces
sors) { |
340 SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = | 394 SkTArray<GrGLInstalledProcessors::Transform, true>& transforms = |
341 installedProcessors->addTransforms(); | 395 installedProcessors->addTransforms(); |
342 const GrProcessor* effect = effectStage.getProcessor(); | 396 const GrFragmentProcessor* effect = effectStage.getProcessor(); |
343 int numTransforms = effect->numTransforms(); | 397 int numTransforms = effect->numTransforms(); |
344 transforms.push_back_n(numTransforms); | 398 transforms.push_back_n(numTransforms); |
345 | 399 |
346 for (int t = 0; t < numTransforms; t++) { | 400 for (int t = 0; t < numTransforms; t++) { |
347 const char* uniName = "StageMatrix"; | 401 const char* uniName = "StageMatrix"; |
348 GrSLType varyingType = | 402 GrSLType varyingType = |
349 effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalC
oords()) ? | 403 effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalC
oords()) ? |
350 kVec3f_GrSLType : | 404 kVec3f_GrSLType : |
351 kVec2f_GrSLType; | 405 kVec2f_GrSLType; |
352 | 406 |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 } | 564 } |
511 | 565 |
512 //////////////////////////////////////////////////////////////////////////////// | 566 //////////////////////////////////////////////////////////////////////////////// |
513 | 567 |
514 GrGLInstalledProcessors::~GrGLInstalledProcessors() { | 568 GrGLInstalledProcessors::~GrGLInstalledProcessors() { |
515 int numEffects = fGLProcessors.count(); | 569 int numEffects = fGLProcessors.count(); |
516 for (int e = 0; e < numEffects; ++e) { | 570 for (int e = 0; e < numEffects; ++e) { |
517 SkDELETE(fGLProcessors[e]); | 571 SkDELETE(fGLProcessors[e]); |
518 } | 572 } |
519 } | 573 } |
OLD | NEW |