OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2014 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "GrGLFullProgramBuilder.h" | |
9 #include "../GrGLGeometryProcessor.h" | |
10 #include "../GrGpuGL.h" | |
11 | |
12 GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu, const GrOptDrawStat
e& optState, | |
13 const GrGLProgramDesc& desc) | |
14 : INHERITED(gpu, optState, desc) | |
15 , fGLGeometryProcessorEmitter(this) | |
16 , fGS(this) | |
17 , fVS(this) { | |
18 } | |
19 | |
20 void | |
21 GrGLFullProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProc
essor, | |
22 const GrFragmentStage* colorStages[
], | |
23 const GrFragmentStage* coverageStag
es[], | |
24 GrGLSLExpr4* inputColor, | |
25 GrGLSLExpr4* inputCoverage) { | |
26 fVS.emitCodeBeforeEffects(inputColor, inputCoverage); | |
27 | |
28 /////////////////////////////////////////////////////////////////////////// | |
29 // emit the per-effect code for both color and coverage effects | |
30 | |
31 EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_
EffectType); | |
32 fColorEffects.reset(this->onCreateAndEmitEffects(colorStages, | |
33 this->desc().numColorEffect
s(), | |
34 colorKeyProvider, | |
35 inputColor)); | |
36 | |
37 if (geometryProcessor) { | |
38 const GrGeometryProcessor& gp = *geometryProcessor->getGeometryProcessor
(); | |
39 fGLGeometryProcessorEmitter.set(&gp); | |
40 fEffectEmitter = &fGLGeometryProcessorEmitter; | |
41 fVS.emitAttributes(gp); | |
42 GrGLSLExpr4 gpInputCoverage = *inputCoverage; | |
43 GrGLSLExpr4 gpOutputCoverage; | |
44 EffectKeyProvider gpKeyProvider(&this->desc(), | |
45 EffectKeyProvider::kGeometryProcessor_EffectType); | |
46 bool useLocalCoords = this->getVertexShaderBuilder()->hasExplicitLocalCo
ords(); | |
47 fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, (1, useLocalC
oords))); | |
48 this->INHERITED::emitEffect(*geometryProcessor, 0, gpKeyProvider, &gpInp
utCoverage, | |
49 &gpOutputCoverage); | |
50 fGeometryProcessor.reset(fProgramEffects.detach()); | |
51 *inputCoverage = gpOutputCoverage; | |
52 } | |
53 | |
54 EffectKeyProvider coverageKeyProvider(&this->desc(), EffectKeyProvider::kCov
erage_EffectType); | |
55 fCoverageEffects.reset(this->onCreateAndEmitEffects(coverageStages, | |
56 this->desc().numCoverage
Effects(), | |
57 coverageKeyProvider, | |
58 inputCoverage)); | |
59 | |
60 fVS.emitCodeAfterEffects(); | |
61 } | |
62 | |
63 void GrGLFullProgramBuilder::addVarying(GrSLType type, | |
64 const char* name, | |
65 const char** vsOutName, | |
66 const char** fsInName, | |
67 GrGLShaderVar::Precision fsPrecision) { | |
68 fVS.addVarying(type, name, vsOutName); | |
69 | |
70 SkString* fsInputName = fVS.fOutputs.back().accessName(); | |
71 | |
72 #if GR_GL_EXPERIMENTAL_GS | |
73 if (desc().getHeader().fExperimentalGS) { | |
74 // TODO let the caller use these names | |
75 fGS.addVarying(type, fsInputName->c_str(), NULL); | |
76 fsInputName = fGS.fOutputs.back().accessName(); | |
77 } | |
78 #endif | |
79 fFS.addVarying(type, fsInputName->c_str(), fsInName, fsPrecision); | |
80 } | |
81 | |
82 GrGLFullProgramBuilder::VaryingHandle | |
83 GrGLFullProgramBuilder::addSeparableVarying(GrSLType type, | |
84 const char* name, | |
85 const char** vsOutName, | |
86 const char** fsInName) { | |
87 addVarying(type, name, vsOutName, fsInName); | |
88 SeparableVaryingInfo& varying = fSeparableVaryingInfos.push_back(); | |
89 varying.fVariable = fFS.fInputs.back(); | |
90 return VaryingHandle::CreateFromSeparableVaryingIndex(fSeparableVaryingInfos
.count() - 1); | |
91 } | |
92 | |
93 GrGLProgramEffects* GrGLFullProgramBuilder::onCreateAndEmitEffects( | |
94 const GrFragmentStage* effectStages[], | |
95 int effectCnt, | |
96 const GrGLProgramDesc::EffectKeyProvider& keyProvider, | |
97 GrGLSLExpr4* inOutFSColor) { | |
98 fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, | |
99 (effectCnt, | |
100 this->getVertexShaderBuilder()->hasExplicitLoc
alCoords()))); | |
101 this->INHERITED::createAndEmitEffects(effectStages, | |
102 effectCnt, | |
103 keyProvider, | |
104 inOutFSColor); | |
105 return fProgramEffects.detach(); | |
106 } | |
107 | |
108 void GrGLFullProgramBuilder::emitEffect(const GrProcessorStage& stage, | |
109 const GrProcessorKey& key, | |
110 const char* outColor, | |
111 const char* inColor, | |
112 int stageIndex) { | |
113 SkASSERT(fProgramEffects.get()); | |
114 const GrProcessor& effect = *stage.getProcessor(); | |
115 SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms()
); | |
116 SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures()); | |
117 | |
118 this->emitTransforms(stage, &coords); | |
119 this->emitSamplers(effect, &samplers); | |
120 | |
121 SkASSERT(fEffectEmitter); | |
122 GrGLProcessor* glEffect = fEffectEmitter->createGLInstance(); | |
123 fProgramEffects->addEffect(glEffect); | |
124 | |
125 // Enclose custom code in a block to avoid namespace conflicts | |
126 SkString openBrace; | |
127 openBrace.printf("{ // Stage %d: %s\n", stageIndex, glEffect->name()); | |
128 fFS.codeAppend(openBrace.c_str()); | |
129 fVS.codeAppend(openBrace.c_str()); | |
130 | |
131 fEffectEmitter->emit(key, outColor, inColor, coords, samplers); | |
132 | |
133 fVS.codeAppend("\t}\n"); | |
134 fFS.codeAppend("\t}\n"); | |
135 } | |
136 | |
137 void GrGLFullProgramBuilder::emitTransforms(const GrProcessorStage& effectStage, | |
138 GrGLProcessor::TransformedCoordsArra
y* outCoords) { | |
139 SkTArray<GrGLVertexProgramEffects::Transform, true>& transforms = | |
140 fProgramEffects->addTransforms(); | |
141 const GrProcessor* effect = effectStage.getProcessor(); | |
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); | |
187 } | |
188 | |
189 const GrGLShaderVar& coords = | |
190 kPosition_GrCoordSet == effect->coordTransform(t).sourceCoords()
? | |
191 fVS.positionAttribute() : | |
192 fVS.localCoordsAttribute(); | |
193 // varying = matrix * coords (logically) | |
194 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyingTyp
e); | |
195 if (kVec2f_GrSLType == varyingType) { | |
196 fVS.codeAppendf("%s = (%s * vec3(%s, 1)).xy;", | |
197 vsVaryingName, uniName, coords.c_str()); | |
198 } else { | |
199 fVS.codeAppendf("%s = %s * vec3(%s, 1);", | |
200 vsVaryingName, uniName, coords.c_str()); | |
201 } | |
202 SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, | |
203 (SkString(fsVaryingName), varyingType)); | |
204 } | |
205 } | |
206 | |
207 bool GrGLFullProgramBuilder::compileAndAttachShaders(GrGLuint programId, | |
208 SkTDArray<GrGLuint>* shader
Ids) const { | |
209 return INHERITED::compileAndAttachShaders(programId, shaderIds) | |
210 && fVS.compileAndAttachShaders(programId, shaderIds) | |
211 #if GR_GL_EXPERIMENTAL_GS | |
212 && (!desc().getHeader().fExperimentalGS | |
213 || fGS.compileAndAttachShaders(programId, shaderIds)) | |
214 #endif | |
215 ; | |
216 } | |
217 | |
218 void GrGLFullProgramBuilder::bindProgramLocations(GrGLuint programId) { | |
219 fVS.bindProgramLocations(programId); | |
220 INHERITED::bindProgramLocations(programId); | |
221 } | |
OLD | NEW |