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 "GrGLFullProgramBuilder.h" | 8 #include "GrGLFullProgramBuilder.h" |
| 9 #include "../GrGLGeometryProcessor.h" |
9 #include "../GrGpuGL.h" | 10 #include "../GrGpuGL.h" |
10 | 11 |
11 GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu, | 12 GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu, |
12 const GrGLProgramDesc& desc) | 13 const GrGLProgramDesc& desc) |
13 : INHERITED(gpu, desc) | 14 : INHERITED(gpu, desc) |
14 , fGS(this) | 15 , fGS(this) |
15 , fVS(this) { | 16 , fVS(this) { |
16 } | 17 } |
17 | 18 |
18 void GrGLFullProgramBuilder::emitCodeBeforeEffects(GrGLSLExpr4* color, | 19 void |
19 GrGLSLExpr4* coverage) { | 20 GrGLFullProgramBuilder::createAndEmitEffects(const GrEffectStage* geometryProces
sor, |
20 fVS.emitCodeBeforeEffects(color, coverage); | 21 const GrEffectStage* colorStages[], |
21 } | 22 const GrEffectStage* coverageStages
[], |
| 23 GrGLSLExpr4* inputColor, |
| 24 GrGLSLExpr4* inputCoverage) { |
| 25 fVS.emitCodeBeforeEffects(inputColor, inputCoverage); |
22 | 26 |
23 void GrGLFullProgramBuilder::emitGeometryProcessor(const GrEffectStage* geometry
Processor, | 27 /////////////////////////////////////////////////////////////////////////// |
24 GrGLSLExpr4* coverage) { | 28 // emit the per-effect code for both color and coverage effects |
| 29 |
| 30 bool useLocalCoords = this->getVertexShaderBuilder()->hasExplicitLocalCoords
(); |
| 31 EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_
EffectType); |
| 32 fColorEffects.reset(this->onCreateAndEmitEffects(colorStages, |
| 33 this->desc().numColorEffect
s(), |
| 34 colorKeyProvider, |
| 35 inputColor)); |
| 36 |
25 if (geometryProcessor) { | 37 if (geometryProcessor) { |
26 GrGLProgramDesc::EffectKeyProvider geometryProcessorKeyProvider( | 38 GrGLSLExpr4 gpInputCoverage = *inputCoverage; |
27 &this->desc(), GrGLProgramDesc::EffectKeyProvider::kGeometryProc
essor_EffectType); | 39 GrGLSLExpr4 gpOutputCoverage; |
28 fGeometryProcessor.reset(this->createAndEmitEffect( | 40 EffectKeyProvider gpKeyProvider(&this->desc(), |
29 geometryProcessor, | 41 EffectKeyProvider::kGeometryProcessor_EffectType); |
30 geometryProcessorKeyProvider, | 42 fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, (1, useLocalC
oords))); |
31 coverage)); | 43 this->INHERITED::emitEffect(*geometryProcessor, 0, gpKeyProvider, &gpInp
utCoverage, |
| 44 &gpOutputCoverage); |
| 45 fGeometryProcessor.reset(fProgramEffects.detach()); |
| 46 *inputCoverage = gpOutputCoverage; |
32 } | 47 } |
33 } | |
34 | 48 |
35 void GrGLFullProgramBuilder::emitCodeAfterEffects() { | 49 EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCov
erage_EffectType); |
36 fVS.emitCodeAfterEffects(); | 50 fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages, |
| 51 this->desc().numCoverage
Effects(), |
| 52 coverageKeyProvider, |
| 53 inputCoverage)); |
| 54 |
| 55 fVS.emitCodeAfterEffects(); |
37 } | 56 } |
38 | 57 |
39 void GrGLFullProgramBuilder::addVarying(GrSLType type, | 58 void GrGLFullProgramBuilder::addVarying(GrSLType type, |
40 const char* name, | 59 const char* name, |
41 const char** vsOutName, | 60 const char** vsOutName, |
42 const char** fsInName, | 61 const char** fsInName, |
43 GrGLShaderVar::Precision fsPrecision) { | 62 GrGLShaderVar::Precision fsPrecision) { |
44 fVS.addVarying(type, name, vsOutName); | 63 fVS.addVarying(type, name, vsOutName); |
45 | 64 |
46 SkString* fsInputName = fVS.fOutputs.back().accessName(); | 65 SkString* fsInputName = fVS.fOutputs.back().accessName(); |
(...skipping 12 matching lines...) Expand all Loading... |
59 GrGLFullProgramBuilder::addSeparableVarying(GrSLType type, | 78 GrGLFullProgramBuilder::addSeparableVarying(GrSLType type, |
60 const char* name, | 79 const char* name, |
61 const char** vsOutName, | 80 const char** vsOutName, |
62 const char** fsInName) { | 81 const char** fsInName) { |
63 addVarying(type, name, vsOutName, fsInName); | 82 addVarying(type, name, vsOutName, fsInName); |
64 SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back(); | 83 SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back(); |
65 varying.fVariable = fFS.fInputs.back(); | 84 varying.fVariable = fFS.fInputs.back(); |
66 return VaryingHandle::CreateFromSeparableVaryingIndex(fSeparableVaryingInfos
.count() - 1); | 85 return VaryingHandle::CreateFromSeparableVaryingIndex(fSeparableVaryingInfos
.count() - 1); |
67 } | 86 } |
68 | 87 |
69 | 88 GrGLProgramEffects* GrGLFullProgramBuilder::onCreateAndEmitEffects( |
70 GrGLProgramEffects* GrGLFullProgramBuilder::createAndEmitEffects( | |
71 const GrEffectStage* effectStages[], | 89 const GrEffectStage* effectStages[], |
72 int effectCnt, | 90 int effectCnt, |
73 const GrGLProgramDesc::EffectKeyProvider& keyProvider, | 91 const GrGLProgramDesc::EffectKeyProvider& keyProvider, |
74 GrGLSLExpr4* inOutFSColor) { | 92 GrGLSLExpr4* inOutFSColor) { |
75 | 93 fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, |
76 GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, effectCnt); | 94 (effectCnt, |
77 this->INHERITED::createAndEmitEffects(&programEffectsBuilder, | 95 this->getVertexShaderBuilder()->hasExplicitLoc
alCoords()))); |
78 effectStages, | 96 this->INHERITED::createAndEmitEffects(effectStages, |
79 effectCnt, | 97 effectCnt, |
80 keyProvider, | 98 keyProvider, |
81 inOutFSColor); | 99 inOutFSColor); |
82 return programEffectsBuilder.finish(); | 100 return fProgramEffects.detach(); |
83 } | 101 } |
84 | 102 |
85 void GrGLFullProgramBuilder::createAndEmitEffect(GrGLProgramEffectsBuilder* prog
ramEffectsBuilder, | 103 void GrGLFullProgramBuilder::emitEffect(const GrEffectStage& stage, |
86 const GrEffectStage* effectStages, | 104 const GrEffectKey& key, |
87 const GrGLProgramDesc::EffectKeyPr
ovider& keyProvider, | 105 const char* outColor, |
88 GrGLSLExpr4* fsInOutColor) { | 106 const char* inColor, |
89 GrGLSLExpr4 inColor = *fsInOutColor; | 107 int stageIndex) { |
90 GrGLSLExpr4 outColor; | 108 SkASSERT(fProgramEffects.get()); |
| 109 const GrEffect& effect = *stage.getEffect(); |
| 110 SkSTArray<2, GrGLEffect::TransformedCoords> coords(effect.numTransforms()); |
| 111 SkSTArray<4, GrGLEffect::TextureSampler> samplers(effect.numTextures()); |
91 | 112 |
92 SkASSERT(effectStages && effectStages->getEffect()); | 113 fVS.emitAttributes(stage); |
93 const GrEffectStage& stage = *effectStages; | 114 this->emitTransforms(stage, &coords); |
| 115 this->emitSamplers(effect, &samplers); |
94 | 116 |
95 // Using scope to force ASR destructor to be triggered | 117 GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect); |
96 { | 118 fProgramEffects->addEffect(glEffect); |
97 CodeStage::AutoStageRestore csar(&fCodeStage, &stage); | |
98 | 119 |
99 if (inColor.isZeros()) { | 120 // Enclose custom code in a block to avoid namespace conflicts |
100 SkString inColorName; | 121 SkString openBrace; |
| 122 openBrace.printf("{ // Stage %d: %s\n", stageIndex, glEffect->name()); |
| 123 fFS.codeAppend(openBrace.c_str()); |
| 124 fVS.codeAppend(openBrace.c_str()); |
101 | 125 |
102 // Effects have no way to communicate zeros, they treat an empty str
ing as ones. | 126 if (glEffect->isVertexEffect()) { |
103 this->nameVariable(&inColorName, '\0', "input"); | 127 GrGLGeometryProcessor* vertexEffect = static_cast<GrGLGeometryProcessor*
>(glEffect); |
104 fFS.codeAppendf("vec4 %s = %s;", inColorName.c_str(), inColor.c_str(
)); | 128 vertexEffect->emitCode(this, effect, key, outColor, inColor, coords, sam
plers); |
105 inColor = inColorName; | 129 } else { |
| 130 glEffect->emitCode(this, effect, key, outColor, inColor, coords, sampler
s); |
| 131 } |
| 132 |
| 133 fVS.codeAppend("\t}\n"); |
| 134 fFS.codeAppend("\t}\n"); |
| 135 } |
| 136 |
| 137 void GrGLFullProgramBuilder::emitTransforms(const GrEffectStage& effectStage, |
| 138 GrGLEffect::TransformedCoordsArray*
outCoords) { |
| 139 SkTArray<GrGLVertexProgramEffects::Transform, true>& transforms = |
| 140 fProgramEffects->addTransforms(); |
| 141 const GrEffect* effect = effectStage.getEffect(); |
| 142 int numTransforms = effect->numTransforms(); |
| 143 transforms.push_back_n(numTransforms); |
| 144 |
| 145 SkTArray<GrGLVertexProgramEffects::PathTransform, true>* pathTransforms = NU
LL; |
| 146 const GrGLCaps* glCaps = this->ctxInfo().caps(); |
| 147 if (glCaps->pathRenderingSupport() && |
| 148 this->gpu()->glPathRendering()->texturingMode() == |
| 149 GrGLPathRendering::SeparableShaders_TexturingMode) { |
| 150 pathTransforms = &fProgramEffects->addPathTransforms(); |
| 151 pathTransforms->push_back_n(numTransforms); |
| 152 } |
| 153 |
| 154 for (int t = 0; t < numTransforms; t++) { |
| 155 const char* uniName = "StageMatrix"; |
| 156 GrSLType varyingType = |
| 157 effectStage.isPerspectiveCoordTransform(t, fVS.hasExplicitLocalC
oords()) ? |
| 158 kVec3f_GrSLType : |
| 159 kVec2f_GrSLType; |
| 160 |
| 161 SkString suffixedUniName; |
| 162 if (0 != t) { |
| 163 suffixedUniName.append(uniName); |
| 164 suffixedUniName.appendf("_%i", t); |
| 165 uniName = suffixedUniName.c_str(); |
| 166 } |
| 167 transforms[t].fHandle = this->addUniform(GrGLProgramBuilder::kVertex_Vis
ibility, |
| 168 kMat33f_GrSLType, |
| 169 uniName, |
| 170 &uniName); |
| 171 |
| 172 const char* varyingName = "MatrixCoord"; |
| 173 SkString suffixedVaryingName; |
| 174 if (0 != t) { |
| 175 suffixedVaryingName.append(varyingName); |
| 176 suffixedVaryingName.appendf("_%i", t); |
| 177 varyingName = suffixedVaryingName.c_str(); |
| 178 } |
| 179 const char* vsVaryingName; |
| 180 const char* fsVaryingName; |
| 181 if (pathTransforms) { |
| 182 (*pathTransforms)[t].fHandle = |
| 183 this->addSeparableVarying(varyingType, varyingName, &vsVaryingNa
me, &fsVaryingName); |
| 184 (*pathTransforms)[t].fType = varyingType; |
| 185 } else { |
| 186 this->addVarying(varyingType, varyingName, &vsVaryingName, &fsVaryin
gName); |
106 } | 187 } |
107 | 188 |
108 // create var to hold stage result | 189 const GrGLShaderVar& coords = |
109 SkString outColorName; | 190 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords()
? |
110 this->nameVariable(&outColorName, '\0', "output"); | 191 fVS.positionAttribute() : |
111 fFS.codeAppendf("vec4 %s;", outColorName.c_str()); | 192 fVS.localCoordsAttribute(); |
112 outColor = outColorName; | 193 // varying = matrix * coords (logically) |
113 | 194 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingTyp
e); |
114 | 195 if (kVec2f_GrSLType == varyingType) { |
115 programEffectsBuilder->emitEffect(stage, | 196 fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;", |
116 keyProvider.get(0), | 197 vsVaryingName, uniName, coords.c_str()); |
117 outColor.c_str(), | 198 } else { |
118 inColor.isOnes() ? NULL : inColor.c_st
r(), | 199 fVS.codeAppendf("%s = %s * vec3(%s, 1);", |
119 fCodeStage.stageIndex()); | 200 vsVaryingName, uniName, coords.c_str()); |
| 201 } |
| 202 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLEffect::TransformedCoords, |
| 203 (SkString(fsVaryingName), varyingType)); |
120 } | 204 } |
121 | |
122 *fsInOutColor = outColor; | |
123 } | |
124 | |
125 GrGLProgramEffects* GrGLFullProgramBuilder::createAndEmitEffect( | |
126 const GrEffectStage* geometryProcessor, | |
127 const GrGLProgramDesc::EffectKeyProvider& keyProvider, | |
128 GrGLSLExpr4* inOutFSColor) { | |
129 | |
130 GrGLVertexProgramEffectsBuilder programEffectsBuilder(this, 1); | |
131 this->createAndEmitEffect(&programEffectsBuilder, geometryProcessor, keyProv
ider, inOutFSColor); | |
132 return programEffectsBuilder.finish(); | |
133 } | 205 } |
134 | 206 |
135 bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId, | 207 bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId, |
136 SkTDArray<GrGLuint>* shader
Ids) const { | 208 SkTDArray<GrGLuint>* shader
Ids) const { |
137 return INHERITED::compileAndAttachShaders(programId, shaderIds) | 209 return INHERITED::compileAndAttachShaders(programId, shaderIds) |
138 && fVS.compileAndAttachShaders(programId, shaderIds) | 210 && fVS.compileAndAttachShaders(programId, shaderIds) |
139 #if GR_GL_EXPERIMENTAL_GS | 211 #if GR_GL_EXPERIMENTAL_GS |
140 && (!desc().getHeader().fExperimentalGS | 212 && (!desc().getHeader().fExperimentalGS |
141 || fGS.compileAndAttachShaders(programId, shaderIds)) | 213 || fGS.compileAndAttachShaders(programId, shaderIds)) |
142 #endif | 214 #endif |
143 ; | 215 ; |
144 } | 216 } |
145 | 217 |
146 void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) { | 218 void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) { |
147 fVS.bindProgramLocations(programId); | 219 fVS.bindProgramLocations(programId); |
148 INHERITED::bindProgramLocations(programId); | 220 INHERITED::bindProgramLocations(programId); |
149 } | 221 } |
OLD | NEW |