blob: 28f1b3822aeaff279efae2777325bb132ff45d88 [file] [log] [blame]
tomhudson@google.comf9ad8862012-05-11 20:38:48 +00001/*
2 * Copyright 2012 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#ifndef GrGLShaderBuilder_DEFINED
9#define GrGLShaderBuilder_DEFINED
10
11#include "GrAllocator.h"
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +000012#include "GrBackendEffectFactory.h"
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000013#include "GrColor.h"
bsalomon@google.coma469c282012-10-24 18:28:34 +000014#include "GrEffect.h"
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000015#include "gl/GrGLSL.h"
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000016#include "gl/GrGLUniformManager.h"
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000017
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000018#include <stdarg.h>
19
bsalomon@google.comad5e9372012-07-11 18:11:27 +000020class GrGLContextInfo;
bsalomon@google.comc7818882013-03-20 19:19:53 +000021class GrEffectStage;
bsalomon@google.com26e18b52013-03-29 19:22:36 +000022class GrGLProgramDesc;
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000023
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000024/**
bsalomon@google.comeb715c82012-07-11 15:03:31 +000025 Contains all the incremental state of a shader as it is being built,as well as helpers to
26 manipulate that state.
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000027*/
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000028class GrGLShaderBuilder {
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000029public:
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000030 /**
bsalomon@google.com34cccde2013-01-04 18:34:30 +000031 * Passed to GrGLEffects to add texture reads to their shader code.
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000032 */
33 class TextureSampler {
34 public:
35 TextureSampler()
commit-bot@chromium.org7425c122013-08-14 18:14:19 +000036 : fConfigComponentMask(0) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000037 // we will memcpy the first 4 bytes from passed in swizzle. This ensures the string is
38 // terminated.
39 fSwizzle[4] = '\0';
40 }
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000041
42 TextureSampler(const TextureSampler& other) { *this = other; }
43
44 TextureSampler& operator= (const TextureSampler& other) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000045 SkASSERT(0 == fConfigComponentMask);
46 SkASSERT(!fSamplerUniform.isValid());
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000047
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000048 fConfigComponentMask = other.fConfigComponentMask;
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000049 fSamplerUniform = other.fSamplerUniform;
50 return *this;
51 }
52
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000053 // bitfield of GrColorComponentFlags present in the texture's config.
54 uint32_t configComponentMask() const { return fConfigComponentMask; }
55
56 const char* swizzle() const { return fSwizzle; }
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000057
bsalomon@google.com26e18b52013-03-29 19:22:36 +000058 bool isInitialized() const { return 0 != fConfigComponentMask; }
59
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000060 private:
bsalomon@google.com34cccde2013-01-04 18:34:30 +000061 // The idx param is used to ensure multiple samplers within a single effect have unique
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000062 // uniform names. swizzle is a four char max string made up of chars 'r', 'g', 'b', and 'a'.
63 void init(GrGLShaderBuilder* builder,
64 uint32_t configComponentMask,
65 const char* swizzle,
66 int idx) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000067 SkASSERT(!this->isInitialized());
68 SkASSERT(0 != configComponentMask);
69 SkASSERT(!fSamplerUniform.isValid());
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000070
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000071 SkASSERT(NULL != builder);
bsalomon@google.com34cccde2013-01-04 18:34:30 +000072 SkString name;
bsalomon@google.com504976e2013-05-09 13:45:02 +000073 name.printf("Sampler%d", idx);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +000074 fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000075 kSampler2D_GrSLType,
bsalomon@google.com34cccde2013-01-04 18:34:30 +000076 name.c_str());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000077 SkASSERT(fSamplerUniform.isValid());
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000078
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000079 fConfigComponentMask = configComponentMask;
80 memcpy(fSwizzle, swizzle, 4);
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000081 }
82
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000083 void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int idx) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000084 SkASSERT(NULL != access);
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000085 this->init(builder,
86 GrPixelConfigComponentMask(access->getTexture()->config()),
87 access->getSwizzle(),
88 idx);
89 }
90
91 uint32_t fConfigComponentMask;
92 char fSwizzle[5];
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000093 GrGLUniformManager::UniformHandle fSamplerUniform;
94
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000095 friend class GrGLShaderBuilder; // to call init().
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000096 };
97
98 typedef SkTArray<TextureSampler> TextureSamplerArray;
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +000099 typedef GrTAllocator<GrGLShaderVar> VarArray;
bsalomon@google.comf06df1b2012-09-06 20:22:31 +0000100
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000101 enum ShaderVisibility {
102 kVertex_Visibility = 0x1,
103 kGeometry_Visibility = 0x2,
104 kFragment_Visibility = 0x4,
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000105 };
106
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000107 GrGLShaderBuilder(const GrGLContextInfo&,
108 GrGLUniformManager&,
109 const GrGLProgramDesc&,
110 bool needsVertexShader);
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000111
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000112 /**
bsalomon@google.com42eff162013-04-02 12:50:49 +0000113 * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
114 * if code is added that uses one of these features without calling enableFeature()
115 */
116 enum GLSLFeature {
117 kStandardDerivatives_GLSLFeature = 0,
118
119 kLastGLSLFeature = kStandardDerivatives_GLSLFeature
120 };
121
122 /**
123 * If the feature is supported then true is returned and any necessary #extension declarations
124 * are added to the shaders. If the feature is not supported then false will be returned.
125 */
126 bool enableFeature(GLSLFeature);
127
128 /**
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000129 * Called by GrGLEffects to add code the fragment shader.
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000130 */
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000131 void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
132 va_list args;
133 va_start(args, format);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000134 fFSCode.appendf(format, args);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000135 va_end(args);
136 }
137
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000138 void fsCodeAppend(const char* str) { fFSCode.append(str); }
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000139
bsalomon@google.comdbe49f72012-11-05 16:36:02 +0000140 /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
141 Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
142 order of the result depends on the GrTextureAccess associated with the TextureSampler. */
bsalomon@google.com868a8e72012-08-30 19:11:34 +0000143 void appendTextureLookup(SkString* out,
bsalomon@google.comf06df1b2012-09-06 20:22:31 +0000144 const TextureSampler&,
bsalomon@google.comdbe49f72012-11-05 16:36:02 +0000145 const char* coordName,
bsalomon@google.com868a8e72012-08-30 19:11:34 +0000146 GrSLType coordType = kVec2f_GrSLType) const;
tomhudson@google.com52598142012-05-24 17:44:30 +0000147
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000148 /** Version of above that appends the result to the fragment shader code instead.*/
149 void fsAppendTextureLookup(const TextureSampler&,
150 const char* coordName,
151 GrSLType coordType = kVec2f_GrSLType);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000152
153
bsalomon@google.com2d8edaf2012-09-07 14:47:31 +0000154 /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
155 always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
156 float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
157 called. */
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000158 void fsAppendTextureLookupAndModulate(const char* modulation,
159 const TextureSampler&,
160 const char* coordName,
161 GrSLType coordType = kVec2f_GrSLType);
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +0000162
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000163 /** Emits a helper function outside of main() in the fragment shader. */
164 void fsEmitFunction(GrSLType returnType,
165 const char* name,
166 int argCnt,
167 const GrGLShaderVar* args,
168 const char* body,
169 SkString* outName);
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000170
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000171 /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
172 GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
173 GrGLShaderVar& fsOutputAppend() { return fFSOutputs.push_back(); }
174 GrGLShaderVar& fsInputAppend(const GrGLShaderVar& var) { return fFSInputs.push_back(var); }
175 GrGLShaderVar& fsOutputAppend(const GrGLShaderVar& var) { return fFSOutputs.push_back(var); }
176
bsalomon@google.com46fba0d2012-10-25 21:42:05 +0000177 /** Generates a EffectKey for the shader code based on the texture access parameters and the
twiz@google.coma5e65ec2012-08-02 15:15:16 +0000178 capabilities of the GL context. This is useful for keying the shader programs that may
179 have multiple representations, based on the type/format of textures used. */
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000180 static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&,
181 const GrGLCaps&);
twiz@google.coma5e65ec2012-08-02 15:15:16 +0000182
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000183 typedef uint8_t DstReadKey;
bsalomon@google.comb5158812013-05-13 18:50:25 +0000184 typedef uint8_t FragPosKey;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000185
186 /** Returns a key for adding code to read the copy-of-dst color in service of effects that
187 require reading the dst. It must not return 0 because 0 indicates that there is no dst
bsalomon@google.comb5158812013-05-13 18:50:25 +0000188 copy read at all (in which case this function should not be called). */
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000189 static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
190
bsalomon@google.comb5158812013-05-13 18:50:25 +0000191 /** Returns a key for reading the fragment location. This should only be called if there is an
192 effect that will requires the fragment position. If the fragment position is not required,
193 the key is 0. */
194 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
195
bsalomon@google.com6d003d12012-09-11 15:45:20 +0000196 /** If texture swizzling is available using tex parameters then it is preferred over mangling
197 the generated shader code. This potentially allows greater reuse of cached shaders. */
198 static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
199
bsalomon@google.com706f6682012-10-23 14:53:55 +0000200 /** Add a uniform variable to the current program, that has visibility in one or more shaders.
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000201 visibility is a bitfield of ShaderVisibility values indicating from which shaders the
202 uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000203 supported at this time. The actual uniform name will be mangled. If outName is not NULL then
204 it will refer to the final uniform name after return. Use the addUniformArray variant to add
205 an array of uniforms.
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000206 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000207 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
208 GrSLType type,
209 const char* name,
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000210 const char** outName = NULL) {
211 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
212 }
213 GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
214 GrSLType type,
215 const char* name,
216 int arrayCount,
217 const char** outName = NULL);
bsalomon@google.com032b2212012-07-16 13:36:18 +0000218
commit-bot@chromium.org7425c122013-08-14 18:14:19 +0000219 const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
220 return fUniformManager.getBuilderUniform(fUniforms, u).fVariable;
221 }
bsalomon@google.com032b2212012-07-16 13:36:18 +0000222
223 /**
bsalomon@google.com706f6682012-10-23 14:53:55 +0000224 * Shortcut for getUniformVariable(u).c_str()
bsalomon@google.com032b2212012-07-16 13:36:18 +0000225 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000226 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
bsalomon@google.com032b2212012-07-16 13:36:18 +0000227 return this->getUniformVariable(u).c_str();
228 }
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000229
bsalomon@google.com706f6682012-10-23 14:53:55 +0000230 /** Returns a variable name that represents the position of the fragment in the FS. The position
231 is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
232 const char* fragmentPosition();
233
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000234 /** Returns the color of the destination pixel. This may be NULL if no effect advertised
235 that it will read the destination. */
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000236 const char* dstColor();
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000237
bsalomon@google.comc7818882013-03-20 19:19:53 +0000238 /**
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000239 * Interfaces used by GrGLProgram.
240 * TODO: Hide these from the GrEffects using friend or splitting this into two related classes.
241 * Also, GrGLProgram's shader string construction should be moved to this class.
242 */
243
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000244 /** Called after building is complete to get the final shader string. To acces the vertex
245 and geometry shaders, use the VertexBuilder. */
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000246 void fsGetShader(SkString*) const;
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000247
bsalomon@google.com504976e2013-05-09 13:45:02 +0000248 /**
249 * Adds code for effects. effectStages contains the effects to add. effectKeys[i] is the key
250 * generated from effectStages[i]. An entry in effectStages can be NULL, in which case it is
251 * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey then it is skipped.
252 * inOutFSColor specifies the input color to the first stage and is updated to be the
253 * output color of the last stage. fsInOutColorKnownValue specifies whether the input color
254 * has a known constant value and is updated to refer to the status of the output color.
255 * The handles to texture samplers for effectStage[i] are added to effectSamplerHandles[i]. The
256 * glEffects array is updated to contain the GrGLEffect generated for each entry in
257 * effectStages.
258 */
259 void emitEffects(const GrEffectStage* effectStages[],
260 const GrBackendEffectFactory::EffectKey effectKeys[],
261 int effectCnt,
262 SkString* inOutFSColor,
263 GrSLConstantVec* fsInOutColorKnownValue,
264 SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
265 GrGLEffect* glEffects[]);
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000266
bsalomon@google.com706f6682012-10-23 14:53:55 +0000267 GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000268 GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
269 return fDstCopyTopLeftUniform;
270 }
271 GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
272 return fDstCopyScaleUniform;
273 }
274 GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
275 return fDstCopySampler.fSamplerUniform;
276 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000277
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000278 /** Helper class used to build the vertex and geometry shaders. This functionality
279 is kept separate from the rest of GrGLShaderBuilder to allow for shaders programs
280 that only use the fragment shader. */
281 class VertexBuilder {
282 public:
283 VertexBuilder(GrGLShaderBuilder* parent, const GrGLProgramDesc&);
284
285 /**
286 * Called by GrGLEffects to add code to one of the shaders.
287 */
288 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
289 va_list args;
290 va_start(args, format);
291 fVSCode.appendf(format, args);
292 va_end(args);
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000293 }
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000294
295 void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
296 va_list args;
297 va_start(args, format);
298 fGSCode.appendf(format, args);
299 va_end(args);
300 }
301
302 void vsCodeAppend(const char* str) { fVSCode.append(str); }
303 void gsCodeAppend(const char* str) { fGSCode.append(str); }
304
305 /** Add a vertex attribute to the current program that is passed in from the vertex data.
306 Returns false if the attribute was already there, true otherwise. */
307 bool addAttribute(GrSLType type, const char* name);
308
309 /** Add a varying variable to the current program to pass values between vertex and fragment
310 shaders. If the last two parameters are non-NULL, they are filled in with the name
311 generated. */
312 void addVarying(GrSLType type,
313 const char* name,
314 const char** vsOutName = NULL,
315 const char** fsInName = NULL);
316
317 /** Returns a vertex attribute that represents the vertex position in the VS. This is the
318 pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
319 */
320 const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
321
322 /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
323 as positionAttribute() or it may not be. It depends upon whether the rendering code
324 specified explicit local coords or not in the GrDrawState. */
325 const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
326
327 /**
328 * Are explicit local coordinates provided as input to the vertex shader.
329 */
330 bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
331
332 /** Called after building is complete to get the final shader string. */
333 void vsGetShader(SkString*) const;
334 void gsGetShader(SkString*) const;
335
336 struct AttributePair {
337 void set(int index, const SkString& name) {
338 fIndex = index; fName = name;
339 }
340 int fIndex;
341 SkString fName;
342 };
343 const SkTArray<AttributePair, true>& getEffectAttributes() const {
344 return fEffectAttributes;
345 }
346 bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
347 const SkString* getEffectAttributeName(int attributeIndex) const;
348
349 // TODO: Everything below here private.
350 public:
351
352 VarArray fVSAttrs;
353 VarArray fVSOutputs;
354 VarArray fGSInputs;
355 VarArray fGSOutputs;
356 SkString fGSHeader; // layout qualifiers specific to GS
357
358 private:
359 GrGLShaderBuilder* fParent;
360
361 bool fUsesGS;
362
363 SkString fVSCode;
364 SkString fGSCode;
365
366 SkSTArray<10, AttributePair, true> fEffectAttributes;
367
368 GrGLShaderVar* fPositionVar;
369 GrGLShaderVar* fLocalCoordsVar;
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000370 };
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000371
372 /** Gets the vertex builder that is used to construct the vertex and geometry shaders.
373 It may be NULL if this shader program is only meant to have a fragment shader. */
374 VertexBuilder* getVertexBuilder() const { return fVertexBuilder.get(); }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000375
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000376 // TODO: Make this do all the compiling, linking, etc.
377 void finished(GrGLuint programID);
bsalomon@google.com706f6682012-10-23 14:53:55 +0000378
robertphillips@google.com13f181f2013-03-02 12:02:08 +0000379 const GrGLContextInfo& ctxInfo() const { return fCtxInfo; }
380
bsalomon@google.com032b2212012-07-16 13:36:18 +0000381private:
bsalomon@google.com032b2212012-07-16 13:36:18 +0000382 void appendDecls(const VarArray&, SkString*) const;
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000383 void appendUniformDecls(ShaderVisibility, SkString*) const;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000384
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000385 typedef GrGLUniformManager::BuilderUniform BuilderUniform;
386 GrGLUniformManager::BuilderUniformArray fUniforms;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000387
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000388private:
bsalomon@google.com504976e2013-05-09 13:45:02 +0000389 class CodeStage : GrNoncopyable {
390 public:
391 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
392
393 bool inStageCode() const {
394 this->validate();
395 return NULL != fEffectStage;
396 }
397
398 const GrEffectStage* effectStage() const {
399 this->validate();
400 return fEffectStage;
401 }
402
403 int stageIndex() const {
skia.committer@gmail.com0f20a3f2013-05-10 07:01:04 +0000404 this->validate();
bsalomon@google.com504976e2013-05-09 13:45:02 +0000405 return fCurrentIndex;
406 }
407
408 class AutoStageRestore : GrNoncopyable {
409 public:
410 AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000411 SkASSERT(NULL != codeStage);
bsalomon@google.com504976e2013-05-09 13:45:02 +0000412 fSavedIndex = codeStage->fCurrentIndex;
413 fSavedEffectStage = codeStage->fEffectStage;
414
415 if (NULL == newStage) {
416 codeStage->fCurrentIndex = -1;
417 } else {
418 codeStage->fCurrentIndex = codeStage->fNextIndex++;
419 }
420 codeStage->fEffectStage = newStage;
421
422 fCodeStage = codeStage;
423 }
424 ~AutoStageRestore() {
425 fCodeStage->fCurrentIndex = fSavedIndex;
426 fCodeStage->fEffectStage = fSavedEffectStage;
427 }
428 private:
429 CodeStage* fCodeStage;
430 int fSavedIndex;
431 const GrEffectStage* fSavedEffectStage;
432 };
433 private:
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000434 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
bsalomon@google.com504976e2013-05-09 13:45:02 +0000435 int fNextIndex;
436 int fCurrentIndex;
437 const GrEffectStage* fEffectStage;
438 } fCodeStage;
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000439
bsalomon@google.com42eff162013-04-02 12:50:49 +0000440 /**
441 * Features that should only be enabled by GrGLShaderBuilder itself.
442 */
443 enum GLSLPrivateFeature {
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000444 kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
445 kEXTShaderFramebufferFetch_GLSLPrivateFeature,
446 kNVShaderFramebufferFetch_GLSLPrivateFeature,
bsalomon@google.com42eff162013-04-02 12:50:49 +0000447 };
448 bool enablePrivateFeature(GLSLPrivateFeature);
449
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000450 // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
451 // track the enables separately for each shader.
bsalomon@google.com42eff162013-04-02 12:50:49 +0000452 void addFSFeature(uint32_t featureBit, const char* extensionName);
453
bsalomon@google.com504976e2013-05-09 13:45:02 +0000454 // Generates a name for a variable. The generated string will be name prefixed by the prefix
455 // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
456 // generating stage code.
457 void nameVariable(SkString* out, char prefix, const char* name);
458
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000459 // Interpretation of DstReadKey when generating code
460 enum {
461 kNoDstRead_DstReadKey = 0,
462 kYesDstRead_DstReadKeyBit = 0x1, // Set if we do a dst-copy-read.
463 kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
464 kTopLeftOrigin_DstReadKeyBit = 0x4, // Set if dst-copy origin is top-left.
465 };
466
bsalomon@google.comb5158812013-05-13 18:50:25 +0000467 enum {
468 kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
469 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
470 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
471 };
472
robertphillips@google.com6177e692013-02-28 20:16:25 +0000473 const GrGLContextInfo& fCtxInfo;
bsalomon@google.com706f6682012-10-23 14:53:55 +0000474 GrGLUniformManager& fUniformManager;
bsalomon@google.com42eff162013-04-02 12:50:49 +0000475 uint32_t fFSFeaturesAddedMask;
bsalomon@google.com706f6682012-10-23 14:53:55 +0000476 SkString fFSFunctions;
bsalomon@google.com42eff162013-04-02 12:50:49 +0000477 SkString fFSExtensions;
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000478 VarArray fFSInputs;
479 VarArray fFSOutputs;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000480
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000481 SkString fFSCode;
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000482
bsalomon@google.com706f6682012-10-23 14:53:55 +0000483 bool fSetupFragPosition;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000484 TextureSampler fDstCopySampler;
485
bsalomon@google.com706f6682012-10-23 14:53:55 +0000486 GrGLUniformManager::UniformHandle fRTHeightUniform;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000487 GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform;
488 GrGLUniformManager::UniformHandle fDstCopyScaleUniform;
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +0000489
bsalomon@google.comb5158812013-05-13 18:50:25 +0000490 bool fTopLeftFragPosRead;
491
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000492 SkAutoTDelete<VertexBuilder> fVertexBuilder;
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000493};
494
495#endif