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 // 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: |
81 /** Generates a shader program. | 111 /** Generates a shader program. |
82 * | 112 * |
83 * The program implements what is specified in the stages given as input. | 113 * The program implements what is specified in the stages given as input. |
84 * After successful generation, the builder result objects are available | 114 * After successful generation, the builder result objects are available |
85 * to be used. | 115 * to be used. |
86 * @return true if generation was successful. | 116 * @return true if generation was successful. |
87 */ | 117 */ |
88 | 118 static GrGLProgram* CreateProgram(const GrOptDrawState&, |
89 bool genProgram(const GrGeometryStage* inGeometryProcessor, | 119 const GrGLProgramDesc&, |
90 const GrFragmentStage* inColorStages[], | 120 GrGpu::DrawType, |
91 const GrFragmentStage* inCoverageStages[]); | 121 const GrGeometryStage* inGeometryProcessor
, |
92 | 122 const GrFragmentStage* inColorStages[], |
93 GrGLProgramEffects* getGeometryProcessor() const { | 123 const GrFragmentStage* inCoverageStages[], |
94 SkASSERT(fProgramID); return fGeometryProcessor.get(); | 124 GrGpuGL* gpu); |
95 } | 125 |
96 GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return f
ColorEffects.get(); } | 126 virtual UniformHandle addUniform(uint32_t visibility, |
97 GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); retur
n fCoverageEffects.get(); } | 127 GrSLType type, |
98 const BuiltinUniformHandles& getBuiltinUniformHandles() const { | 128 const char* name, |
99 SkASSERT(fProgramID); | 129 const char** outName = NULL) SK_OVERRIDE { |
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); | 130 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); |
123 } | 131 } |
124 GrGLProgramDataManager::UniformHandle addUniformArray(uint32_t visibility, | 132 virtual UniformHandle addUniformArray(uint32_t visibility, |
125 GrSLType type, | 133 GrSLType type, |
126 const char* name, | 134 const char* name, |
127 int arrayCount, | 135 int arrayCount, |
128 const char** outName =
NULL); | 136 const char** outName = NULL) SK_OVERRI
DE; |
129 | 137 |
130 const GrGLShaderVar& getUniformVariable(GrGLProgramDataManager::UniformHandl
e u) const { | 138 virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const SK_OV
ERRIDE { |
131 return fUniforms[u.toShaderBuilderIndex()].fVariable; | 139 return fUniforms[u.toShaderBuilderIndex()].fVariable; |
132 } | 140 } |
133 | 141 |
134 /** | 142 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(); | 143 return this->getUniformVariable(u).c_str(); |
139 } | 144 } |
140 | 145 |
141 const GrGLContextInfo& ctxInfo() const; | 146 virtual const GrGLContextInfo& ctxInfo() const SK_OVERRIDE; |
142 | 147 |
143 GrGLFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; } | 148 virtual GrGpuGL* gpu() const SK_OVERRIDE { return fGpu; } |
144 GrGpuGL* gpu() const { return fGpu; } | 149 |
| 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 }; |
145 | 175 |
146 protected: | 176 protected: |
147 typedef GrTAllocator<GrGLShaderVar> VarArray; | 177 static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&, |
| 178 const GrOptDrawState&, |
| 179 GrGpu::DrawType, |
| 180 bool hasGeometryProcessor, |
| 181 GrGpuGL*); |
| 182 |
148 GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&); | 183 GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&); |
149 | 184 |
150 const GrOptDrawState& optState() const { return fOptState; } | 185 const GrOptDrawState& optState() const { return fOptState; } |
151 const GrGLProgramDesc& desc() const { return fDesc; } | 186 const GrGLProgramDesc& desc() const { return fDesc; } |
152 | 187 const GrGLProgramDesc::KeyHeader& header() const { return fDesc.getHeader();
} |
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); | |
176 | 188 |
177 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix | 189 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix |
178 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're | 190 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're |
179 // generating stage code. | 191 // generating stage code. |
180 void nameVariable(SkString* out, char prefix, const char* name); | 192 void nameVariable(SkString* out, char prefix, const char* name); |
181 | 193 void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExp
r4* inputCoverage); |
182 virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>
* shaderIds) const; | 194 void createAndEmitProcessors(const GrGeometryStage* geometryProcessor, |
183 | 195 const GrFragmentStage* colorStages[], |
184 virtual void bindProgramLocations(GrGLuint programId); | 196 const GrFragmentStage* coverageStages[], |
185 void resolveProgramLocations(GrGLuint programId); | 197 GrGLSLExpr4* inputColor, |
186 | 198 GrGLSLExpr4* inputCoverage); |
187 void appendDecls(const VarArray&, SkString*) const; | 199 template <class ProcessorStage> |
| 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 |
188 void appendUniformDecls(ShaderVisibility, SkString*) const; | 226 void appendUniformDecls(ShaderVisibility, SkString*) const; |
189 | 227 |
190 class CodeStage : SkNoncopyable { | 228 // reset is called by program creator between each processor's emit code. I
t increments the |
| 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 { |
191 public: | 240 public: |
192 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} | 241 AutoStageRestore(GrGLProgramBuilder* pb) |
193 | 242 : fPB(pb), fOutOfStage(pb->fOutOfStage) { pb->exitStage(); } |
194 bool inStageCode() const { | 243 ~AutoStageRestore() { fPB->fOutOfStage = fOutOfStage; } |
195 this->validate(); | 244 private: |
196 return SkToBool(fEffectStage); | 245 GrGLProgramBuilder* fPB; |
| 246 bool fOutOfStage; |
| 247 }; |
| 248 class AutoStageAdvance { |
| 249 public: |
| 250 AutoStageAdvance(GrGLProgramBuilder* pb) : fPB(pb) { fPB->reset(); } |
| 251 ~AutoStageAdvance() { fPB->exitStage(); } |
| 252 private: |
| 253 GrGLProgramBuilder* fPB; |
| 254 }; |
| 255 void exitStage() { fOutOfStage = true; } |
| 256 void enterStage() { fOutOfStage = false; } |
| 257 int stageIndex() const { return fStageIndex; } |
| 258 |
| 259 typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider; |
| 260 typedef GrGLProgramDataManager::UniformInfo UniformInfo; |
| 261 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; |
| 262 |
| 263 // number of each input/output type in a single allocation block, used by ma
ny builders |
| 264 static const int kVarsPerBlock; |
| 265 |
| 266 BuiltinUniformHandles fUniformHandles; |
| 267 GrGLVertexBuilder fVS; |
| 268 GrGLGeometryBuilder fGS; |
| 269 GrGLFragmentShaderBuilder fFS; |
| 270 bool fOutOfStage; |
| 271 int fStageIndex; |
| 272 |
| 273 SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor; |
| 274 SkAutoTUnref<GrGLInstalledProcessors> fColorEffects; |
| 275 SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects; |
| 276 |
| 277 const GrOptDrawState& fOptState; |
| 278 const GrGLProgramDesc& fDesc; |
| 279 GrGpuGL* fGpu; |
| 280 UniformInfoArray fUniforms; |
| 281 |
| 282 friend class GrGLShaderBuilder; |
| 283 friend class GrGLVertexBuilder; |
| 284 friend class GrGLFragmentShaderBuilder; |
| 285 friend class GrGLGeometryBuilder; |
| 286 }; |
| 287 |
| 288 /** |
| 289 * This class encapsulates an array of GrGLProcessors and their supporting data
(coord transforms |
| 290 * and textures). It is built by GrGLProgramBuilder, then used to manage the nec
essary GL |
| 291 * state and shader uniforms in GLPrograms. Its just Plain old data, and as suc
h is entirely public |
| 292 * |
| 293 * TODO We really don't need this class to have an array of processors. It make
s sense for it |
| 294 * to just have one, also break out the transforms |
| 295 */ |
| 296 class GrGLInstalledProcessors : public SkRefCnt { |
| 297 public: |
| 298 GrGLInstalledProcessors(int reserveCount, bool hasExplicitLocalCoords = fals
e) |
| 299 : fGLProcessors(reserveCount) |
| 300 , fSamplers(reserveCount) |
| 301 , fTransforms(reserveCount) |
| 302 , fHasExplicitLocalCoords(hasExplicitLocalCoords) { |
| 303 } |
| 304 |
| 305 virtual ~GrGLInstalledProcessors(); |
| 306 |
| 307 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
| 308 |
| 309 struct Sampler { |
| 310 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) |
| 311 UniformHandle fUniform; |
| 312 int fTextureUnit; |
| 313 }; |
| 314 |
| 315 class ShaderVarHandle { |
| 316 public: |
| 317 bool isValid() const { return fHandle > -1; } |
| 318 ShaderVarHandle() : fHandle(-1) {} |
| 319 ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid());
} |
| 320 int handle() const { SkASSERT(this->isValid()); return fHandle; } |
| 321 UniformHandle convertToUniformHandle() { |
| 322 SkASSERT(this->isValid()); |
| 323 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex
(fHandle); |
197 } | 324 } |
198 | 325 |
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 }; | |
234 private: | 326 private: |
235 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurre
ntIndex)); } | 327 int fHandle; |
236 int fNextIndex; | 328 }; |
237 int fCurrentIndex; | 329 |
238 const GrProcessorStage* fEffectStage; | 330 struct Transform { |
239 }; | 331 Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidM
atrix(); } |
240 | 332 ShaderVarHandle fHandle; |
241 class GrGLProcessorEmitterInterface { | 333 SkMatrix fCurrentValue; |
242 public: | 334 GrSLType fType; |
243 virtual ~GrGLProcessorEmitterInterface() {} | 335 }; |
244 virtual GrGLProcessor* createGLInstance() = 0; | 336 |
245 virtual void emit(const GrProcessorKey& key, | 337 void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); } |
246 const char* outColor, | 338 SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); } |
247 const char* inColor, | 339 SkTArray<Transform, true>& addTransforms() { return fTransforms.push_back();
} |
248 const GrGLProcessor::TransformedCoordsArray& coords, | 340 |
249 const GrGLProcessor::TextureSamplerArray& samplers) =
0; | 341 SkTArray<GrGLProcessor*> fGLProcessors; |
250 }; | 342 SkTArray<SkSTArray<4, Sampler, true> > fSamplers; |
251 | 343 SkTArray<SkSTArray<2, Transform, true> > fTransforms; |
252 class GrGLFragmentProcessorEmitter : public GrGLProcessorEmitterInterface { | 344 bool fHasExplicitLocalCoords; |
253 public: | |
254 GrGLFragmentProcessorEmitter(GrGLProgramBuilder* builder) | |
255 : fBuilder(builder) | |
256 , fFragmentProcessor(NULL) | |
257 , fGLFragmentProcessor(NULL) {} | |
258 virtual ~GrGLFragmentProcessorEmitter() {} | |
259 void set(const GrFragmentProcessor* fp) { | |
260 SkASSERT(NULL == fFragmentProcessor); | |
261 fFragmentProcessor = fp; | |
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 } | |
283 private: | |
284 GrGLProgramBuilder* fBuilder; | |
285 const GrFragmentProcessor* fFragmentProcessor; | |
286 GrGLFragmentProcessor* fGLFragmentProcessor; | |
287 }; | |
288 | |
289 GrGLProcessorEmitterInterface* fEffectEmitter; | |
290 CodeStage fCodeStage; | |
291 SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor; | |
292 SkAutoTUnref<GrGLProgramEffects> fColorEffects; | |
293 SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; | |
294 BuiltinUniformHandles fUniformHandles; | |
295 bool fFragOnly; | |
296 int fTexCoordSetCnt; | |
297 GrGLuint fProgramID; | |
298 GrGLFragmentShaderBuilder fFS; | |
299 SeparableVaryingInfoArray fSeparableVaryingInfos; | |
300 | |
301 private: | |
302 virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor, | |
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; | |
334 | 345 |
335 friend class GrGLShaderBuilder; | 346 friend class GrGLShaderBuilder; |
336 friend class GrGLVertexShaderBuilder; | 347 friend class GrGLVertexShaderBuilder; |
337 friend class GrGLFragmentShaderBuilder; | 348 friend class GrGLFragmentShaderBuilder; |
338 friend class GrGLGeometryShaderBuilder; | 349 friend class GrGLGeometryShaderBuilder; |
339 }; | 350 }; |
340 | 351 |
341 #endif | 352 #endif |
OLD | NEW |