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