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 #ifndef GrGLProgramBuilder_DEFINED | 8 #ifndef GrGLProgramBuilder_DEFINED |
9 #define GrGLProgramBuilder_DEFINED | 9 #define GrGLProgramBuilder_DEFINED |
10 | 10 |
| 11 #include "GrAllocator.h" |
| 12 #include "GrBackendProcessorFactory.h" |
| 13 #include "GrColor.h" |
| 14 #include "GrProcessor.h" |
11 #include "GrGLFragmentShaderBuilder.h" | 15 #include "GrGLFragmentShaderBuilder.h" |
12 #include "GrGLGeometryShaderBuilder.h" | 16 #include "GrGLGeometryShaderBuilder.h" |
13 #include "GrGLVertexShaderBuilder.h" | 17 #include "GrGLVertexShaderBuilder.h" |
14 #include "../GrGLProgramDataManager.h" | 18 #include "SkTypes.h" |
15 #include "../GrGLUniformHandle.h" | 19 #include "gl/GrGLProcessor.h" |
| 20 #include "gl/GrGLProgramDesc.h" |
| 21 #include "gl/GrGLProgramEffects.h" |
| 22 #include "gl/GrGLSL.h" |
| 23 #include "gl/GrGLProgramDataManager.h" |
16 | 24 |
17 class GrGLInstalledProcessors; | 25 #include <stdarg.h> |
18 | 26 |
19 /* | 27 class GrGLContextInfo; |
20 * This is the base class for a series of interfaces. This base class *MUST* re
main abstract with | 28 class GrProcessorStage; |
21 * NO data members because it is used in multiple interface inheritance. | 29 class GrGLProgramDesc; |
22 * Heirarchy: | 30 |
23 * GrGLUniformBuilder | 31 /** |
24 * / \ | 32 Contains all the incremental state of a shader as it is being built,as well as
helpers to |
25 * GrGLFPBuilder GrGLGPBuilder | 33 manipulate that state. |
26 * \ / | 34 */ |
27 * GrGLProgramBuilder(internal use only) | 35 class GrGLProgramBuilder { |
28 */ | |
29 class GrGLUniformBuilder { | |
30 public: | 36 public: |
31 enum ShaderVisibility { | 37 enum ShaderVisibility { |
32 kVertex_Visibility = 0x1, | 38 kVertex_Visibility = 0x1, |
33 kGeometry_Visibility = 0x2, | 39 kGeometry_Visibility = 0x2, |
34 kFragment_Visibility = 0x4, | 40 kFragment_Visibility = 0x4, |
35 }; | 41 }; |
36 | 42 |
37 virtual ~GrGLUniformBuilder() {} | 43 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
| 44 typedef GrGLProgramDataManager::VaryingHandle VaryingHandle; |
38 | 45 |
39 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 46 // Handles for program uniforms (other than per-effect uniforms) |
| 47 struct BuiltinUniformHandles { |
| 48 UniformHandle fViewMatrixUni; |
| 49 UniformHandle fRTAdjustmentUni; |
| 50 UniformHandle fColorUni; |
| 51 UniformHandle fCoverageUni; |
| 52 |
| 53 // We use the render target height to provide a y-down frag coord when s
pecifying |
| 54 // origin_upper_left is not supported. |
| 55 UniformHandle fRTHeightUni; |
| 56 |
| 57 // Uniforms for computing texture coords to do the dst-copy lookup |
| 58 UniformHandle fDstCopyTopLeftUni; |
| 59 UniformHandle fDstCopyScaleUni; |
| 60 UniformHandle fDstCopySamplerUni; |
| 61 }; |
| 62 |
| 63 struct UniformInfo { |
| 64 GrGLShaderVar fVariable; |
| 65 uint32_t fVisibility; |
| 66 GrGLint fLocation; |
| 67 }; |
| 68 |
| 69 // This uses an allocator rather than array so that the GrGLShaderVars don't
move in memory |
| 70 // after they are inserted. Users of GrGLShaderBuilder get refs to the vars
and ptrs to their |
| 71 // name strings. Otherwise, we'd have to hand out copies. |
| 72 typedef GrTAllocator<UniformInfo> UniformInfoArray; |
| 73 |
| 74 struct SeparableVaryingInfo { |
| 75 GrGLShaderVar fVariable; |
| 76 GrGLint fLocation; |
| 77 }; |
| 78 |
| 79 typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray; |
| 80 |
| 81 /** Generates a shader program. |
| 82 * |
| 83 * The program implements what is specified in the stages given as input. |
| 84 * After successful generation, the builder result objects are available |
| 85 * to be used. |
| 86 * @return true if generation was successful. |
| 87 */ |
| 88 |
| 89 bool genProgram(const GrGeometryStage* inGeometryProcessor, |
| 90 const GrFragmentStage* inColorStages[], |
| 91 const GrFragmentStage* inCoverageStages[]); |
| 92 |
| 93 GrGLProgramEffects* getGeometryProcessor() const { |
| 94 SkASSERT(fProgramID); return fGeometryProcessor.get(); |
| 95 } |
| 96 GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return f
ColorEffects.get(); } |
| 97 GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); retur
n fCoverageEffects.get(); } |
| 98 const BuiltinUniformHandles& getBuiltinUniformHandles() const { |
| 99 SkASSERT(fProgramID); |
| 100 return fUniformHandles; |
| 101 } |
| 102 GrGLuint getProgramID() const { SkASSERT(fProgramID); return fProgramID; } |
| 103 bool hasVertexShader() const { SkASSERT(fProgramID); return !fFragOnly; } |
| 104 int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetC
nt; } |
| 105 const UniformInfoArray& getUniformInfos() const { return fUniforms; } |
| 106 const SeparableVaryingInfoArray& getSeparableVaryingInfos() const { |
| 107 return fSeparableVaryingInfos; |
| 108 } |
| 109 |
| 110 virtual ~GrGLProgramBuilder() {} |
40 | 111 |
41 /** Add a uniform variable to the current program, that has visibility in on
e or more shaders. | 112 /** Add a uniform variable to the current program, that has visibility in on
e or more shaders. |
42 visibility is a bitfield of ShaderVisibility values indicating from whic
h shaders the | 113 visibility is a bitfield of ShaderVisibility values indicating from whic
h shaders the |
43 uniform should be accessible. At least one bit must be set. Geometry sha
der uniforms are not | 114 uniform should be accessible. At least one bit must be set. Geometry sha
der uniforms are not |
44 supported at this time. The actual uniform name will be mangled. If outN
ame is not NULL then | 115 supported at this time. The actual uniform name will be mangled. If outN
ame is not NULL then |
45 it will refer to the final uniform name after return. Use the addUniform
Array variant to add | 116 it will refer to the final uniform name after return. Use the addUniform
Array variant to add |
46 an array of uniforms. */ | 117 an array of uniforms. */ |
47 virtual UniformHandle addUniform(uint32_t visibility, | 118 GrGLProgramDataManager::UniformHandle addUniform(uint32_t visibility, |
48 GrSLType type, | 119 GrSLType type, |
49 const char* name, | 120 const char* name, |
50 const char** outName = NULL) = 0; | 121 const char** outName = NULL
) { |
51 virtual UniformHandle addUniformArray(uint32_t visibility, | 122 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); |
52 GrSLType type, | 123 } |
53 const char* name, | 124 GrGLProgramDataManager::UniformHandle addUniformArray(uint32_t visibility, |
54 int arrayCount, | 125 GrSLType type, |
55 const char** outName = NULL) = 0; | 126 const char* name, |
56 | 127 int arrayCount, |
57 virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const = 0; | 128 const char** outName =
NULL); |
| 129 |
| 130 const GrGLShaderVar& getUniformVariable(GrGLProgramDataManager::UniformHandl
e u) const { |
| 131 return fUniforms[u.toShaderBuilderIndex()].fVariable; |
| 132 } |
58 | 133 |
59 /** | 134 /** |
60 * Shortcut for getUniformVariable(u).c_str() | 135 * Shortcut for getUniformVariable(u).c_str() |
61 */ | 136 */ |
62 virtual const char* getUniformCStr(UniformHandle u) const = 0; | 137 const char* getUniformCStr(GrGLProgramDataManager::UniformHandle u) const { |
63 | |
64 virtual const GrGLContextInfo& ctxInfo() const = 0; | |
65 | |
66 virtual GrGpuGL* gpu() const = 0; | |
67 | |
68 /* | |
69 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE | |
70 */ | |
71 }; | |
72 | |
73 /* a specialization of the above for GPs. Lets the user add uniforms, varyings,
and VS / FS code */ | |
74 class GrGLGPBuilder : public virtual GrGLUniformBuilder { | |
75 public: | |
76 virtual void addVarying(GrSLType type, | |
77 const char* name, | |
78 const char** vsOutName = NULL, | |
79 const char** fsInName = NULL, | |
80 GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::
kDefault_Precision) = 0; | |
81 | |
82 // TODO rename getFragmentBuilder | |
83 virtual GrGLGPFragmentBuilder* getFragmentShaderBuilder() = 0; | |
84 virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0; | |
85 | |
86 /* | |
87 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE | |
88 */ | |
89 }; | |
90 | |
91 /* a specializations for FPs. Lets the user add uniforms and FS code */ | |
92 class GrGLFPBuilder : public virtual GrGLUniformBuilder { | |
93 public: | |
94 virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() = 0; | |
95 | |
96 /* | |
97 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE | |
98 */ | |
99 }; | |
100 | |
101 /* | |
102 * Please note - no diamond problems because of virtual inheritance. Also, both
base classes | |
103 * are pure virtual with no data members. This is the base class for program bu
ilding. | |
104 * Subclasses are nearly identical but each has their own way of emitting transf
orms. State for | |
105 * each of the elements of the shader pipeline, ie vertex, fragment, geometry, e
tc, lives in those | |
106 * respective builders | |
107 */ | |
108 class GrGLProgramBuilder : public GrGLGPBuilder, | |
109 public GrGLFPBuilder { | |
110 public: | |
111 /** Generates a shader program. | |
112 * | |
113 * The program implements what is specified in the stages given as input. | |
114 * After successful generation, the builder result objects are available | |
115 * to be used. | |
116 * @return true if generation was successful. | |
117 */ | |
118 static GrGLProgram* CreateProgram(const GrOptDrawState&, | |
119 const GrGLProgramDesc&, | |
120 GrGpu::DrawType, | |
121 const GrGeometryStage* inGeometryProcessor
, | |
122 const GrFragmentStage* inColorStages[], | |
123 const GrFragmentStage* inCoverageStages[], | |
124 GrGpuGL* gpu); | |
125 | |
126 virtual UniformHandle addUniform(uint32_t visibility, | |
127 GrSLType type, | |
128 const char* name, | |
129 const char** outName = NULL) SK_OVERRIDE { | |
130 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); | |
131 } | |
132 virtual UniformHandle addUniformArray(uint32_t visibility, | |
133 GrSLType type, | |
134 const char* name, | |
135 int arrayCount, | |
136 const char** outName = NULL) SK_OVERRI
DE; | |
137 | |
138 virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const SK_OV
ERRIDE { | |
139 return fUniforms[u.toShaderBuilderIndex()].fVariable; | |
140 } | |
141 | |
142 virtual const char* getUniformCStr(UniformHandle u) const SK_OVERRIDE { | |
143 return this->getUniformVariable(u).c_str(); | 138 return this->getUniformVariable(u).c_str(); |
144 } | 139 } |
145 | 140 |
146 virtual const GrGLContextInfo& ctxInfo() const SK_OVERRIDE; | 141 const GrGLContextInfo& ctxInfo() const; |
147 | 142 |
148 virtual GrGpuGL* gpu() const SK_OVERRIDE { return fGpu; } | 143 GrGLFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; } |
149 | 144 GrGpuGL* gpu() const { return fGpu; } |
150 virtual GrGLFragmentShaderBuilder* getFragmentShaderBuilder() SK_OVERRIDE {
return &fFS; } | |
151 virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fV
S; } | |
152 | |
153 virtual void addVarying(GrSLType type, | |
154 const char* name, | |
155 const char** vsOutName = NULL, | |
156 const char** fsInName = NULL, | |
157 GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::
kDefault_Precision); | |
158 | |
159 // Handles for program uniforms (other than per-effect uniforms) | |
160 struct BuiltinUniformHandles { | |
161 UniformHandle fViewMatrixUni; | |
162 UniformHandle fRTAdjustmentUni; | |
163 UniformHandle fColorUni; | |
164 UniformHandle fCoverageUni; | |
165 | |
166 // We use the render target height to provide a y-down frag coord when s
pecifying | |
167 // origin_upper_left is not supported. | |
168 UniformHandle fRTHeightUni; | |
169 | |
170 // Uniforms for computing texture coords to do the dst-copy lookup | |
171 UniformHandle fDstCopyTopLeftUni; | |
172 UniformHandle fDstCopyScaleUni; | |
173 UniformHandle fDstCopySamplerUni; | |
174 }; | |
175 | 145 |
176 protected: | 146 protected: |
177 static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&, | 147 typedef GrTAllocator<GrGLShaderVar> VarArray; |
178 const GrOptDrawState&, | |
179 GrGpu::DrawType, | |
180 bool hasGeometryProcessor, | |
181 GrGpuGL*); | |
182 | |
183 GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&); | 148 GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&); |
184 | 149 |
185 const GrOptDrawState& optState() const { return fOptState; } | 150 const GrOptDrawState& optState() const { return fOptState; } |
186 const GrGLProgramDesc& desc() const { return fDesc; } | 151 const GrGLProgramDesc& desc() const { return fDesc; } |
187 const GrGLProgramDesc::KeyHeader& header() const { return fDesc.getHeader();
} | 152 |
| 153 // Helper for emitEffects(). |
| 154 void createAndEmitEffects(const GrFragmentStage* effectStages[], |
| 155 int effectCnt, |
| 156 const GrGLProgramDesc::EffectKeyProvider&, |
| 157 GrGLSLExpr4* inOutFSColor); |
| 158 |
| 159 /* |
| 160 * A helper function called to emit the geometry processor as well as indivi
dual coverage |
| 161 * and color stages. this will call into subclasses emit effect |
| 162 */ |
| 163 void emitEffect(const GrProcessorStage& effectStage, |
| 164 int effectIndex, |
| 165 const GrGLProgramDesc::EffectKeyProvider& keyProvider, |
| 166 GrGLSLExpr4* inColor, |
| 167 GrGLSLExpr4* outColor); |
| 168 |
| 169 /** |
| 170 * Helper for emitEffect() in subclasses. Emits uniforms for an effect's tex
ture accesses and |
| 171 * appends the necessary data to the TextureSamplerArray* object so effects
can add texture |
| 172 * lookups to their code. This method is only meant to be called during the
construction phase. |
| 173 */ |
| 174 void emitSamplers(const GrProcessor& effect, |
| 175 GrGLProcessor::TextureSamplerArray* outSamplers); |
188 | 176 |
189 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix | 177 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix |
190 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're | 178 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're |
191 // generating stage code. | 179 // generating stage code. |
192 void nameVariable(SkString* out, char prefix, const char* name); | 180 void nameVariable(SkString* out, char prefix, const char* name); |
193 void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExp
r4* inputCoverage); | 181 |
194 void createAndEmitProcessors(const GrGeometryStage* geometryProcessor, | 182 virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>
* shaderIds) const; |
195 const GrFragmentStage* colorStages[], | 183 |
196 const GrFragmentStage* coverageStages[], | 184 virtual void bindProgramLocations(GrGLuint programId); |
197 GrGLSLExpr4* inputColor, | 185 void resolveProgramLocations(GrGLuint programId); |
198 GrGLSLExpr4* inputCoverage); | 186 |
199 template <class ProcessorStage> | 187 void appendDecls(const VarArray&, SkString*) const; |
200 void createAndEmitProcessors(const ProcessorStage*[], | |
201 int effectCnt, | |
202 const GrGLProgramDesc::EffectKeyProvider&, | |
203 GrGLSLExpr4* fsInOutColor, | |
204 GrGLInstalledProcessors*); | |
205 void verify(const GrGeometryProcessor&); | |
206 void verify(const GrFragmentProcessor&); | |
207 void emitSamplers(const GrProcessor&, | |
208 GrGLProcessor::TextureSamplerArray* outSamplers, | |
209 GrGLInstalledProcessors*); | |
210 | |
211 // each specific program builder has a distinct transform and must override
this function | |
212 virtual void emitTransforms(const GrProcessorStage&, | |
213 GrGLProcessor::TransformedCoordsArray* outCoords
, | |
214 GrGLInstalledProcessors*); | |
215 GrGLProgram* finalize(); | |
216 void bindUniformLocations(GrGLuint programID); | |
217 bool checkLinkStatus(GrGLuint programID); | |
218 void resolveUniformLocations(GrGLuint programID); | |
219 | |
220 void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs
); | |
221 void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs); | |
222 | |
223 // Subclasses create different programs | |
224 virtual GrGLProgram* createProgram(GrGLuint programID); | |
225 | |
226 void appendUniformDecls(ShaderVisibility, SkString*) const; | 188 void appendUniformDecls(ShaderVisibility, SkString*) const; |
227 | 189 |
228 // reset is called by program creator between each processor's emit code. I
t increments the | 190 class CodeStage : SkNoncopyable { |
229 // stage offset for variable name mangling, and also ensures verfication var
iables in the | |
230 // fragment shader are cleared. | |
231 void reset() { | |
232 this->enterStage(); | |
233 this->addStage(); | |
234 fFS.reset(); | |
235 } | |
236 void addStage() { fStageIndex++; } | |
237 | |
238 // This simple class exits the stage and then restores the stage when it goe
s out of scope | |
239 class AutoStageRestore { | |
240 public: | 191 public: |
241 AutoStageRestore(GrGLProgramBuilder* pb) | 192 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} |
242 : fPB(pb), fOutOfStage(pb->fOutOfStage) { pb->exitStage(); } | 193 |
243 ~AutoStageRestore() { fPB->fOutOfStage = fOutOfStage; } | 194 bool inStageCode() const { |
| 195 this->validate(); |
| 196 return SkToBool(fEffectStage); |
| 197 } |
| 198 |
| 199 const GrProcessorStage* effectStage() const { |
| 200 this->validate(); |
| 201 return fEffectStage; |
| 202 } |
| 203 |
| 204 int stageIndex() const { |
| 205 this->validate(); |
| 206 return fCurrentIndex; |
| 207 } |
| 208 |
| 209 class AutoStageRestore : SkNoncopyable { |
| 210 public: |
| 211 AutoStageRestore(CodeStage* codeStage, const GrProcessorStage* newSt
age) { |
| 212 SkASSERT(codeStage); |
| 213 fSavedIndex = codeStage->fCurrentIndex; |
| 214 fSavedEffectStage = codeStage->fEffectStage; |
| 215 |
| 216 if (NULL == newStage) { |
| 217 codeStage->fCurrentIndex = -1; |
| 218 } else { |
| 219 codeStage->fCurrentIndex = codeStage->fNextIndex++; |
| 220 } |
| 221 codeStage->fEffectStage = newStage; |
| 222 |
| 223 fCodeStage = codeStage; |
| 224 } |
| 225 ~AutoStageRestore() { |
| 226 fCodeStage->fCurrentIndex = fSavedIndex; |
| 227 fCodeStage->fEffectStage = fSavedEffectStage; |
| 228 } |
| 229 private: |
| 230 CodeStage* fCodeStage; |
| 231 int fSavedIndex; |
| 232 const GrProcessorStage* fSavedEffectStage; |
| 233 }; |
244 private: | 234 private: |
245 GrGLProgramBuilder* fPB; | 235 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurre
ntIndex)); } |
246 bool fOutOfStage; | 236 int fNextIndex; |
| 237 int fCurrentIndex; |
| 238 const GrProcessorStage* fEffectStage; |
247 }; | 239 }; |
248 void exitStage() { fOutOfStage = true; } | 240 |
249 void enterStage() { fOutOfStage = false; } | 241 class GrGLProcessorEmitterInterface { |
250 int stageIndex() const { return fStageIndex; } | 242 public: |
251 | 243 virtual ~GrGLProcessorEmitterInterface() {} |
252 typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider; | 244 virtual GrGLProcessor* createGLInstance() = 0; |
253 typedef GrGLProgramDataManager::UniformInfo UniformInfo; | 245 virtual void emit(const GrProcessorKey& key, |
254 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; | 246 const char* outColor, |
255 | 247 const char* inColor, |
256 // number of each input/output type in a single allocation block, used by ma
ny builders | 248 const GrGLProcessor::TransformedCoordsArray& coords, |
257 static const int kVarsPerBlock; | 249 const GrGLProcessor::TextureSamplerArray& samplers) =
0; |
258 | |
259 BuiltinUniformHandles fUniformHandles; | |
260 GrGLVertexBuilder fVS; | |
261 GrGLGeometryBuilder fGS; | |
262 GrGLFragmentShaderBuilder fFS; | |
263 bool fOutOfStage; | |
264 int fStageIndex; | |
265 | |
266 SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor; | |
267 SkAutoTUnref<GrGLInstalledProcessors> fColorEffects; | |
268 SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects; | |
269 | |
270 const GrOptDrawState& fOptState; | |
271 const GrGLProgramDesc& fDesc; | |
272 GrGpuGL* fGpu; | |
273 UniformInfoArray fUniforms; | |
274 | |
275 friend class GrGLShaderBuilder; | |
276 friend class GrGLVertexBuilder; | |
277 friend class GrGLFragmentShaderBuilder; | |
278 friend class GrGLGeometryBuilder; | |
279 }; | |
280 | |
281 /** | |
282 * This class encapsulates an array of GrGLProcessors and their supporting data
(coord transforms | |
283 * and textures). It is built by GrGLProgramBuilder, then used to manage the nec
essary GL | |
284 * state and shader uniforms in GLPrograms. Its just Plain old data, and as suc
h is entirely public | |
285 * | |
286 * TODO We really don't need this class to have an array of processors. It make
s sense for it | |
287 * to just have one, also break out the transforms | |
288 */ | |
289 class GrGLInstalledProcessors : public SkRefCnt { | |
290 public: | |
291 GrGLInstalledProcessors(int reserveCount, bool hasExplicitLocalCoords = fals
e) | |
292 : fGLProcessors(reserveCount) | |
293 , fSamplers(reserveCount) | |
294 , fTransforms(reserveCount) | |
295 , fHasExplicitLocalCoords(hasExplicitLocalCoords) { | |
296 } | |
297 | |
298 virtual ~GrGLInstalledProcessors(); | |
299 | |
300 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | |
301 | |
302 struct Sampler { | |
303 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) | |
304 UniformHandle fUniform; | |
305 int fTextureUnit; | |
306 }; | 250 }; |
307 | 251 |
308 class ShaderVarHandle { | 252 class GrGLFragmentProcessorEmitter : public GrGLProcessorEmitterInterface { |
309 public: | 253 public: |
310 bool isValid() const { return fHandle > -1; } | 254 GrGLFragmentProcessorEmitter(GrGLProgramBuilder* builder) |
311 ShaderVarHandle() : fHandle(-1) {} | 255 : fBuilder(builder) |
312 ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid());
} | 256 , fFragmentProcessor(NULL) |
313 int handle() const { SkASSERT(this->isValid()); return fHandle; } | 257 , fGLFragmentProcessor(NULL) {} |
314 UniformHandle convertToUniformHandle() { | 258 virtual ~GrGLFragmentProcessorEmitter() {} |
315 SkASSERT(this->isValid()); | 259 void set(const GrFragmentProcessor* fp) { |
316 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex
(fHandle); | 260 SkASSERT(NULL == fFragmentProcessor); |
317 } | 261 fFragmentProcessor = fp; |
318 | 262 } |
| 263 virtual GrGLProcessor* createGLInstance() { |
| 264 SkASSERT(fFragmentProcessor); |
| 265 SkASSERT(NULL == fGLFragmentProcessor); |
| 266 fGLFragmentProcessor = |
| 267 fFragmentProcessor->getFactory().createGLInstance(*fFragment
Processor); |
| 268 return fGLFragmentProcessor; |
| 269 } |
| 270 virtual void emit(const GrProcessorKey& key, |
| 271 const char* outColor, |
| 272 const char* inColor, |
| 273 const GrGLProcessor::TransformedCoordsArray& coords, |
| 274 const GrGLProcessor::TextureSamplerArray& samplers) { |
| 275 SkASSERT(fFragmentProcessor); |
| 276 SkASSERT(fGLFragmentProcessor); |
| 277 fGLFragmentProcessor->emitCode(fBuilder, *fFragmentProcessor, key, o
utColor, inColor, |
| 278 coords, samplers); |
| 279 // this will not leak because it hasa already been used by createGLI
nstance |
| 280 fGLFragmentProcessor = NULL; |
| 281 fFragmentProcessor = NULL; |
| 282 } |
319 private: | 283 private: |
320 int fHandle; | 284 GrGLProgramBuilder* fBuilder; |
| 285 const GrFragmentProcessor* fFragmentProcessor; |
| 286 GrGLFragmentProcessor* fGLFragmentProcessor; |
321 }; | 287 }; |
322 | 288 |
323 struct Transform { | 289 GrGLProcessorEmitterInterface* fEffectEmitter; |
324 Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidM
atrix(); } | 290 CodeStage fCodeStage; |
325 ShaderVarHandle fHandle; | 291 SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor; |
326 SkMatrix fCurrentValue; | 292 SkAutoTUnref<GrGLProgramEffects> fColorEffects; |
327 GrSLType fType; | 293 SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; |
328 }; | 294 BuiltinUniformHandles fUniformHandles; |
329 | 295 bool fFragOnly; |
330 void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); } | 296 int fTexCoordSetCnt; |
331 SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); } | 297 GrGLuint fProgramID; |
332 SkTArray<Transform, true>& addTransforms() { return fTransforms.push_back();
} | 298 GrGLFragmentShaderBuilder fFS; |
333 | 299 SeparableVaryingInfoArray fSeparableVaryingInfos; |
334 SkTArray<GrGLProcessor*> fGLProcessors; | 300 |
335 SkTArray<SkSTArray<4, Sampler, true> > fSamplers; | 301 private: |
336 SkTArray<SkSTArray<2, Transform, true> > fTransforms; | 302 virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor, |
337 bool fHasExplicitLocalCoords; | 303 const GrFragmentStage* colorStages[], |
| 304 const GrFragmentStage* coverageStages[], |
| 305 GrGLSLExpr4* inputColor, |
| 306 GrGLSLExpr4* inputCoverage) = 0; |
| 307 /* |
| 308 * Subclasses override emitEffect below to emit data and code for a specific
single effect |
| 309 */ |
| 310 virtual void emitEffect(const GrProcessorStage&, |
| 311 const GrProcessorKey&, |
| 312 const char* outColor, |
| 313 const char* inColor, |
| 314 int stageIndex) = 0; |
| 315 |
| 316 /* |
| 317 * Because we have fragment only builders, and those builders need to implem
ent a subclass |
| 318 * of program effects, we have to have base classes overload the program eff
ects here |
| 319 */ |
| 320 virtual GrGLProgramEffects* getProgramEffects() = 0; |
| 321 |
| 322 /** |
| 323 * Compiles all the shaders, links them into a program, and writes the progr
am id to the output |
| 324 * struct. |
| 325 **/ |
| 326 bool finish(); |
| 327 |
| 328 GrGLFragmentProcessorEmitter fGrProcessorEmitter; |
| 329 |
| 330 const GrOptDrawState& fOptState; |
| 331 const GrGLProgramDesc& fDesc; |
| 332 GrGpuGL* fGpu; |
| 333 UniformInfoArray fUniforms; |
338 | 334 |
339 friend class GrGLShaderBuilder; | 335 friend class GrGLShaderBuilder; |
340 friend class GrGLVertexShaderBuilder; | 336 friend class GrGLVertexShaderBuilder; |
341 friend class GrGLFragmentShaderBuilder; | 337 friend class GrGLFragmentShaderBuilder; |
342 friend class GrGLGeometryShaderBuilder; | 338 friend class GrGLGeometryShaderBuilder; |
343 }; | 339 }; |
344 | 340 |
345 #endif | 341 #endif |
OLD | NEW |