blob: ad0d87ef31bffd8c5e3cc45a1ec491f313c75412 [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;
99
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000100 enum ShaderVisibility {
101 kVertex_Visibility = 0x1,
102 kGeometry_Visibility = 0x2,
103 kFragment_Visibility = 0x4,
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000104 };
105
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000106 GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLProgramDesc&);
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000107
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000108 /**
bsalomon@google.com42eff162013-04-02 12:50:49 +0000109 * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
110 * if code is added that uses one of these features without calling enableFeature()
111 */
112 enum GLSLFeature {
113 kStandardDerivatives_GLSLFeature = 0,
114
115 kLastGLSLFeature = kStandardDerivatives_GLSLFeature
116 };
117
118 /**
119 * If the feature is supported then true is returned and any necessary #extension declarations
120 * are added to the shaders. If the feature is not supported then false will be returned.
121 */
122 bool enableFeature(GLSLFeature);
123
124 /**
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000125 * Called by GrGLEffects to add code to one of the shaders.
126 */
127 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
128 va_list args;
129 va_start(args, format);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000130 fVSCode.appendf(format, args);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000131 va_end(args);
132 }
133
134 void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
135 va_list args;
136 va_start(args, format);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000137 fGSCode.appendf(format, args);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000138 va_end(args);
139 }
140
141 void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
142 va_list args;
143 va_start(args, format);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000144 fFSCode.appendf(format, args);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000145 va_end(args);
146 }
147
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000148 void vsCodeAppend(const char* str) { fVSCode.append(str); }
149 void gsCodeAppend(const char* str) { fGSCode.append(str); }
150 void fsCodeAppend(const char* str) { fFSCode.append(str); }
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000151
bsalomon@google.comdbe49f72012-11-05 16:36:02 +0000152 /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
153 Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
154 order of the result depends on the GrTextureAccess associated with the TextureSampler. */
bsalomon@google.com868a8e72012-08-30 19:11:34 +0000155 void appendTextureLookup(SkString* out,
bsalomon@google.comf06df1b2012-09-06 20:22:31 +0000156 const TextureSampler&,
bsalomon@google.comdbe49f72012-11-05 16:36:02 +0000157 const char* coordName,
bsalomon@google.com868a8e72012-08-30 19:11:34 +0000158 GrSLType coordType = kVec2f_GrSLType) const;
tomhudson@google.com52598142012-05-24 17:44:30 +0000159
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000160 /** Version of above that appends the result to the fragment shader code instead.*/
161 void fsAppendTextureLookup(const TextureSampler&,
162 const char* coordName,
163 GrSLType coordType = kVec2f_GrSLType);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000164
165
bsalomon@google.com2d8edaf2012-09-07 14:47:31 +0000166 /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
167 always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
168 float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
169 called. */
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000170 void fsAppendTextureLookupAndModulate(const char* modulation,
171 const TextureSampler&,
172 const char* coordName,
173 GrSLType coordType = kVec2f_GrSLType);
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +0000174
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000175 /** Emits a helper function outside of main() in the fragment shader. */
176 void fsEmitFunction(GrSLType returnType,
177 const char* name,
178 int argCnt,
179 const GrGLShaderVar* args,
180 const char* body,
181 SkString* outName);
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000182
bsalomon@google.com46fba0d2012-10-25 21:42:05 +0000183 /** Generates a EffectKey for the shader code based on the texture access parameters and the
twiz@google.coma5e65ec2012-08-02 15:15:16 +0000184 capabilities of the GL context. This is useful for keying the shader programs that may
185 have multiple representations, based on the type/format of textures used. */
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000186 static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&,
187 const GrGLCaps&);
twiz@google.coma5e65ec2012-08-02 15:15:16 +0000188
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000189 typedef uint8_t DstReadKey;
bsalomon@google.comb5158812013-05-13 18:50:25 +0000190 typedef uint8_t FragPosKey;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000191
192 /** Returns a key for adding code to read the copy-of-dst color in service of effects that
193 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 +0000194 copy read at all (in which case this function should not be called). */
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000195 static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
196
bsalomon@google.comb5158812013-05-13 18:50:25 +0000197 /** Returns a key for reading the fragment location. This should only be called if there is an
198 effect that will requires the fragment position. If the fragment position is not required,
199 the key is 0. */
200 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
201
bsalomon@google.com6d003d12012-09-11 15:45:20 +0000202 /** If texture swizzling is available using tex parameters then it is preferred over mangling
203 the generated shader code. This potentially allows greater reuse of cached shaders. */
204 static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
205
bsalomon@google.com706f6682012-10-23 14:53:55 +0000206 /** 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 +0000207 visibility is a bitfield of ShaderVisibility values indicating from which shaders the
208 uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000209 supported at this time. The actual uniform name will be mangled. If outName is not NULL then
210 it will refer to the final uniform name after return. Use the addUniformArray variant to add
211 an array of uniforms.
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000212 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000213 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
214 GrSLType type,
215 const char* name,
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000216 const char** outName = NULL) {
217 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
218 }
219 GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
220 GrSLType type,
221 const char* name,
222 int arrayCount,
223 const char** outName = NULL);
bsalomon@google.com032b2212012-07-16 13:36:18 +0000224
commit-bot@chromium.org7425c122013-08-14 18:14:19 +0000225 const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
226 return fUniformManager.getBuilderUniform(fUniforms, u).fVariable;
227 }
bsalomon@google.com032b2212012-07-16 13:36:18 +0000228
229 /**
bsalomon@google.com706f6682012-10-23 14:53:55 +0000230 * Shortcut for getUniformVariable(u).c_str()
bsalomon@google.com032b2212012-07-16 13:36:18 +0000231 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000232 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
bsalomon@google.com032b2212012-07-16 13:36:18 +0000233 return this->getUniformVariable(u).c_str();
234 }
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000235
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000236 /** Add a vertex attribute to the current program that is passed in from the vertex data.
237 Returns false if the attribute was already there, true otherwise. */
238 bool addAttribute(GrSLType type, const char* name);
239
240 /** Add a varying variable to the current program to pass values between vertex and fragment
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000241 shaders. If the last two parameters are non-NULL, they are filled in with the name
242 generated. */
tomhudson@google.com23cb2292012-05-30 18:26:03 +0000243 void addVarying(GrSLType type,
244 const char* name,
245 const char** vsOutName = NULL,
246 const char** fsInName = NULL);
247
bsalomon@google.com706f6682012-10-23 14:53:55 +0000248 /** Returns a variable name that represents the position of the fragment in the FS. The position
249 is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
250 const char* fragmentPosition();
251
bsalomon@google.com17504f52012-10-30 12:34:25 +0000252 /** Returns a vertex attribute that represents the vertex position in the VS. This is the
253 pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
254 */
255 const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
256
bsalomon@google.comc7818882013-03-20 19:19:53 +0000257 /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
258 as positionAttribute() or it may not be. It depends upon whether the rendering code
259 specified explicit local coords or not in the GrDrawState. */
260 const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
261
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000262 /** Returns the color of the destination pixel. This may be NULL if no effect advertised
263 that it will read the destination. */
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000264 const char* dstColor();
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000265
bsalomon@google.comc7818882013-03-20 19:19:53 +0000266 /**
267 * Are explicit local coordinates provided as input to the vertex shader.
268 */
269 bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
270
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000271 /**
272 * Interfaces used by GrGLProgram.
273 * TODO: Hide these from the GrEffects using friend or splitting this into two related classes.
274 * Also, GrGLProgram's shader string construction should be moved to this class.
275 */
276
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000277 /** Called after building is complete to get the final shader string. */
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000278 void vsGetShader(SkString*) const;
279 void gsGetShader(SkString*) const;
280 void fsGetShader(SkString*) const;
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000281
bsalomon@google.com504976e2013-05-09 13:45:02 +0000282 /**
283 * Adds code for effects. effectStages contains the effects to add. effectKeys[i] is the key
284 * generated from effectStages[i]. An entry in effectStages can be NULL, in which case it is
285 * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey then it is skipped.
286 * inOutFSColor specifies the input color to the first stage and is updated to be the
287 * output color of the last stage. fsInOutColorKnownValue specifies whether the input color
288 * has a known constant value and is updated to refer to the status of the output color.
289 * The handles to texture samplers for effectStage[i] are added to effectSamplerHandles[i]. The
290 * glEffects array is updated to contain the GrGLEffect generated for each entry in
291 * effectStages.
292 */
293 void emitEffects(const GrEffectStage* effectStages[],
294 const GrBackendEffectFactory::EffectKey effectKeys[],
295 int effectCnt,
296 SkString* inOutFSColor,
297 GrSLConstantVec* fsInOutColorKnownValue,
298 SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
299 GrGLEffect* glEffects[]);
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000300
bsalomon@google.com706f6682012-10-23 14:53:55 +0000301 GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000302 GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
303 return fDstCopyTopLeftUniform;
304 }
305 GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
306 return fDstCopyScaleUniform;
307 }
308 GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
309 return fDstCopySampler.fSamplerUniform;
310 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000311
312 struct AttributePair {
313 void set(int index, const SkString& name) {
314 fIndex = index; fName = name;
315 }
316 int fIndex;
317 SkString fName;
318 };
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000319 const SkTArray<AttributePair, true>& getEffectAttributes() const {
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000320 return fEffectAttributes;
321 }
322 const SkString* getEffectAttributeName(int attributeIndex) const;
323
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000324 // TODO: Make this do all the compiling, linking, etc.
325 void finished(GrGLuint programID);
bsalomon@google.com706f6682012-10-23 14:53:55 +0000326
robertphillips@google.com13f181f2013-03-02 12:02:08 +0000327 const GrGLContextInfo& ctxInfo() const { return fCtxInfo; }
328
bsalomon@google.com032b2212012-07-16 13:36:18 +0000329private:
330 typedef GrTAllocator<GrGLShaderVar> VarArray;
331
bsalomon@google.com032b2212012-07-16 13:36:18 +0000332 void appendDecls(const VarArray&, SkString*) const;
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000333 void appendUniformDecls(ShaderVisibility, SkString*) const;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000334
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000335 typedef GrGLUniformManager::BuilderUniform BuilderUniform;
336 GrGLUniformManager::BuilderUniformArray fUniforms;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000337
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000338 // TODO: Everything below here private.
bsalomon@google.com032b2212012-07-16 13:36:18 +0000339public:
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000340
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000341 VarArray fVSAttrs;
342 VarArray fVSOutputs;
343 VarArray fGSInputs;
344 VarArray fGSOutputs;
345 VarArray fFSInputs;
346 SkString fGSHeader; // layout qualifiers specific to GS
bsalomon@google.comf0a104e2012-07-10 17:51:07 +0000347 VarArray fFSOutputs;
tomhudson@google.com040c41a2012-05-18 14:57:40 +0000348
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000349private:
bsalomon@google.com504976e2013-05-09 13:45:02 +0000350 class CodeStage : GrNoncopyable {
351 public:
352 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
353
354 bool inStageCode() const {
355 this->validate();
356 return NULL != fEffectStage;
357 }
358
359 const GrEffectStage* effectStage() const {
360 this->validate();
361 return fEffectStage;
362 }
363
364 int stageIndex() const {
skia.committer@gmail.com0f20a3f2013-05-10 07:01:04 +0000365 this->validate();
bsalomon@google.com504976e2013-05-09 13:45:02 +0000366 return fCurrentIndex;
367 }
368
369 class AutoStageRestore : GrNoncopyable {
370 public:
371 AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000372 SkASSERT(NULL != codeStage);
bsalomon@google.com504976e2013-05-09 13:45:02 +0000373 fSavedIndex = codeStage->fCurrentIndex;
374 fSavedEffectStage = codeStage->fEffectStage;
375
376 if (NULL == newStage) {
377 codeStage->fCurrentIndex = -1;
378 } else {
379 codeStage->fCurrentIndex = codeStage->fNextIndex++;
380 }
381 codeStage->fEffectStage = newStage;
382
383 fCodeStage = codeStage;
384 }
385 ~AutoStageRestore() {
386 fCodeStage->fCurrentIndex = fSavedIndex;
387 fCodeStage->fEffectStage = fSavedEffectStage;
388 }
389 private:
390 CodeStage* fCodeStage;
391 int fSavedIndex;
392 const GrEffectStage* fSavedEffectStage;
393 };
394 private:
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000395 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
bsalomon@google.com504976e2013-05-09 13:45:02 +0000396 int fNextIndex;
397 int fCurrentIndex;
398 const GrEffectStage* fEffectStage;
399 } fCodeStage;
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000400
bsalomon@google.com42eff162013-04-02 12:50:49 +0000401 /**
402 * Features that should only be enabled by GrGLShaderBuilder itself.
403 */
404 enum GLSLPrivateFeature {
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000405 kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
406 kEXTShaderFramebufferFetch_GLSLPrivateFeature,
407 kNVShaderFramebufferFetch_GLSLPrivateFeature,
bsalomon@google.com42eff162013-04-02 12:50:49 +0000408 };
409 bool enablePrivateFeature(GLSLPrivateFeature);
410
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000411 // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
412 // track the enables separately for each shader.
bsalomon@google.com42eff162013-04-02 12:50:49 +0000413 void addFSFeature(uint32_t featureBit, const char* extensionName);
414
bsalomon@google.com504976e2013-05-09 13:45:02 +0000415 // Generates a name for a variable. The generated string will be name prefixed by the prefix
416 // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
417 // generating stage code.
418 void nameVariable(SkString* out, char prefix, const char* name);
419
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000420 // Interpretation of DstReadKey when generating code
421 enum {
422 kNoDstRead_DstReadKey = 0,
423 kYesDstRead_DstReadKeyBit = 0x1, // Set if we do a dst-copy-read.
424 kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
425 kTopLeftOrigin_DstReadKeyBit = 0x4, // Set if dst-copy origin is top-left.
426 };
427
bsalomon@google.comb5158812013-05-13 18:50:25 +0000428 enum {
429 kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
430 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
431 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
432 };
433
robertphillips@google.com6177e692013-02-28 20:16:25 +0000434 const GrGLContextInfo& fCtxInfo;
bsalomon@google.com706f6682012-10-23 14:53:55 +0000435 GrGLUniformManager& fUniformManager;
bsalomon@google.com42eff162013-04-02 12:50:49 +0000436 uint32_t fFSFeaturesAddedMask;
bsalomon@google.com706f6682012-10-23 14:53:55 +0000437 SkString fFSFunctions;
bsalomon@google.com42eff162013-04-02 12:50:49 +0000438 SkString fFSExtensions;
bsalomon@google.com706f6682012-10-23 14:53:55 +0000439
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000440 bool fUsesGS;
441
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000442 SkString fFSCode;
443 SkString fVSCode;
444 SkString fGSCode;
445
bsalomon@google.com706f6682012-10-23 14:53:55 +0000446 bool fSetupFragPosition;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000447 TextureSampler fDstCopySampler;
448
bsalomon@google.com706f6682012-10-23 14:53:55 +0000449 GrGLUniformManager::UniformHandle fRTHeightUniform;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000450 GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform;
451 GrGLUniformManager::UniformHandle fDstCopyScaleUniform;
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +0000452
bsalomon@google.comb5158812013-05-13 18:50:25 +0000453 bool fTopLeftFragPosRead;
454
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000455 SkSTArray<10, AttributePair, true> fEffectAttributes;
456
bsalomon@google.com17504f52012-10-30 12:34:25 +0000457 GrGLShaderVar* fPositionVar;
bsalomon@google.comc7818882013-03-20 19:19:53 +0000458 GrGLShaderVar* fLocalCoordsVar;
459
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000460};
461
462#endif