blob: d73a731a7cd9aaf52d7518d5dfb66413553740b8 [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"
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000015#include "SkTypes.h"
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000016#include "gl/GrGLSL.h"
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000017#include "gl/GrGLUniformManager.h"
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000018
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000019#include <stdarg.h>
20
bsalomon@google.comad5e9372012-07-11 18:11:27 +000021class GrGLContextInfo;
bsalomon@google.comc7818882013-03-20 19:19:53 +000022class GrEffectStage;
bsalomon@google.com26e18b52013-03-29 19:22:36 +000023class GrGLProgramDesc;
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000024
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000025/**
bsalomon@google.comeb715c82012-07-11 15:03:31 +000026 Contains all the incremental state of a shader as it is being built,as well as helpers to
27 manipulate that state.
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000028*/
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000029class GrGLShaderBuilder {
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000030public:
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000031 /**
bsalomon@google.com34cccde2013-01-04 18:34:30 +000032 * Passed to GrGLEffects to add texture reads to their shader code.
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000033 */
34 class TextureSampler {
35 public:
36 TextureSampler()
commit-bot@chromium.org7425c122013-08-14 18:14:19 +000037 : fConfigComponentMask(0) {
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000038 // we will memcpy the first 4 bytes from passed in swizzle. This ensures the string is
39 // terminated.
40 fSwizzle[4] = '\0';
41 }
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000042
43 TextureSampler(const TextureSampler& other) { *this = other; }
44
45 TextureSampler& operator= (const TextureSampler& other) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000046 SkASSERT(0 == fConfigComponentMask);
47 SkASSERT(!fSamplerUniform.isValid());
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000048
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000049 fConfigComponentMask = other.fConfigComponentMask;
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000050 fSamplerUniform = other.fSamplerUniform;
51 return *this;
52 }
53
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000054 // bitfield of GrColorComponentFlags present in the texture's config.
55 uint32_t configComponentMask() const { return fConfigComponentMask; }
56
57 const char* swizzle() const { return fSwizzle; }
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000058
bsalomon@google.com26e18b52013-03-29 19:22:36 +000059 bool isInitialized() const { return 0 != fConfigComponentMask; }
60
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000061 private:
bsalomon@google.com34cccde2013-01-04 18:34:30 +000062 // The idx param is used to ensure multiple samplers within a single effect have unique
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000063 // uniform names. swizzle is a four char max string made up of chars 'r', 'g', 'b', and 'a'.
64 void init(GrGLShaderBuilder* builder,
65 uint32_t configComponentMask,
66 const char* swizzle,
67 int idx) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000068 SkASSERT(!this->isInitialized());
69 SkASSERT(0 != configComponentMask);
70 SkASSERT(!fSamplerUniform.isValid());
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000071
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000072 SkASSERT(NULL != builder);
bsalomon@google.com34cccde2013-01-04 18:34:30 +000073 SkString name;
bsalomon@google.com504976e2013-05-09 13:45:02 +000074 name.printf("Sampler%d", idx);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +000075 fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000076 kSampler2D_GrSLType,
bsalomon@google.com34cccde2013-01-04 18:34:30 +000077 name.c_str());
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000078 SkASSERT(fSamplerUniform.isValid());
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000079
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000080 fConfigComponentMask = configComponentMask;
81 memcpy(fSwizzle, swizzle, 4);
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000082 }
83
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000084 void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int idx) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +000085 SkASSERT(NULL != access);
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000086 this->init(builder,
87 GrPixelConfigComponentMask(access->getTexture()->config()),
88 access->getSwizzle(),
89 idx);
90 }
91
92 uint32_t fConfigComponentMask;
93 char fSwizzle[5];
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000094 GrGLUniformManager::UniformHandle fSamplerUniform;
95
bsalomon@google.comb8eb2e82013-03-28 13:46:42 +000096 friend class GrGLShaderBuilder; // to call init().
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000097 };
98
99 typedef SkTArray<TextureSampler> TextureSamplerArray;
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000100 typedef GrTAllocator<GrGLShaderVar> VarArray;
bsalomon@google.comf06df1b2012-09-06 20:22:31 +0000101
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000102 enum ShaderVisibility {
103 kVertex_Visibility = 0x1,
104 kGeometry_Visibility = 0x2,
105 kFragment_Visibility = 0x4,
bsalomon@google.comeb715c82012-07-11 15:03:31 +0000106 };
107
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000108 GrGLShaderBuilder(GrGpuGL*,
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000109 GrGLUniformManager&,
110 const GrGLProgramDesc&,
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000111 bool needsVertexShader);
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000112
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000113 /**
bsalomon@google.com42eff162013-04-02 12:50:49 +0000114 * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
115 * if code is added that uses one of these features without calling enableFeature()
116 */
117 enum GLSLFeature {
118 kStandardDerivatives_GLSLFeature = 0,
119
120 kLastGLSLFeature = kStandardDerivatives_GLSLFeature
121 };
122
123 /**
124 * If the feature is supported then true is returned and any necessary #extension declarations
125 * are added to the shaders. If the feature is not supported then false will be returned.
126 */
127 bool enableFeature(GLSLFeature);
128
129 /**
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000130 * Called by GrGLEffects to add code the fragment shader.
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000131 */
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000132 void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
133 va_list args;
134 va_start(args, format);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000135 fFSCode.appendf(format, args);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000136 va_end(args);
137 }
138
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000139 void fsCodeAppend(const char* str) { fFSCode.append(str); }
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000140
bsalomon@google.comdbe49f72012-11-05 16:36:02 +0000141 /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
142 Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
143 order of the result depends on the GrTextureAccess associated with the TextureSampler. */
bsalomon@google.com868a8e72012-08-30 19:11:34 +0000144 void appendTextureLookup(SkString* out,
bsalomon@google.comf06df1b2012-09-06 20:22:31 +0000145 const TextureSampler&,
bsalomon@google.comdbe49f72012-11-05 16:36:02 +0000146 const char* coordName,
bsalomon@google.com868a8e72012-08-30 19:11:34 +0000147 GrSLType coordType = kVec2f_GrSLType) const;
tomhudson@google.com52598142012-05-24 17:44:30 +0000148
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000149 /** Version of above that appends the result to the fragment shader code instead.*/
150 void fsAppendTextureLookup(const TextureSampler&,
151 const char* coordName,
152 GrSLType coordType = kVec2f_GrSLType);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000153
154
bsalomon@google.com2d8edaf2012-09-07 14:47:31 +0000155 /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
156 always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
157 float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
158 called. */
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000159 void fsAppendTextureLookupAndModulate(const char* modulation,
160 const TextureSampler&,
161 const char* coordName,
162 GrSLType coordType = kVec2f_GrSLType);
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +0000163
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000164 /** Emits a helper function outside of main() in the fragment shader. */
165 void fsEmitFunction(GrSLType returnType,
166 const char* name,
167 int argCnt,
168 const GrGLShaderVar* args,
169 const char* body,
170 SkString* outName);
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000171
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000172 /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
173 GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000174
bsalomon@google.com46fba0d2012-10-25 21:42:05 +0000175 /** Generates a EffectKey for the shader code based on the texture access parameters and the
twiz@google.coma5e65ec2012-08-02 15:15:16 +0000176 capabilities of the GL context. This is useful for keying the shader programs that may
177 have multiple representations, based on the type/format of textures used. */
bsalomon@google.com2eaaefd2012-10-29 19:51:22 +0000178 static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTextureAccess&,
179 const GrGLCaps&);
twiz@google.coma5e65ec2012-08-02 15:15:16 +0000180
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000181 typedef uint8_t DstReadKey;
bsalomon@google.comb5158812013-05-13 18:50:25 +0000182 typedef uint8_t FragPosKey;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000183
184 /** Returns a key for adding code to read the copy-of-dst color in service of effects that
185 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 +0000186 copy read at all (in which case this function should not be called). */
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000187 static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
188
bsalomon@google.comb5158812013-05-13 18:50:25 +0000189 /** Returns a key for reading the fragment location. This should only be called if there is an
190 effect that will requires the fragment position. If the fragment position is not required,
191 the key is 0. */
192 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
193
bsalomon@google.com6d003d12012-09-11 15:45:20 +0000194 /** If texture swizzling is available using tex parameters then it is preferred over mangling
195 the generated shader code. This potentially allows greater reuse of cached shaders. */
196 static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
197
bsalomon@google.com706f6682012-10-23 14:53:55 +0000198 /** 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 +0000199 visibility is a bitfield of ShaderVisibility values indicating from which shaders the
200 uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000201 supported at this time. The actual uniform name will be mangled. If outName is not NULL then
202 it will refer to the final uniform name after return. Use the addUniformArray variant to add
203 an array of uniforms.
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000204 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000205 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
206 GrSLType type,
207 const char* name,
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000208 const char** outName = NULL) {
209 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
210 }
211 GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
212 GrSLType type,
213 const char* name,
214 int arrayCount,
215 const char** outName = NULL);
bsalomon@google.com032b2212012-07-16 13:36:18 +0000216
commit-bot@chromium.org7425c122013-08-14 18:14:19 +0000217 const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
218 return fUniformManager.getBuilderUniform(fUniforms, u).fVariable;
219 }
bsalomon@google.com032b2212012-07-16 13:36:18 +0000220
221 /**
bsalomon@google.com706f6682012-10-23 14:53:55 +0000222 * Shortcut for getUniformVariable(u).c_str()
bsalomon@google.com032b2212012-07-16 13:36:18 +0000223 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000224 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
bsalomon@google.com032b2212012-07-16 13:36:18 +0000225 return this->getUniformVariable(u).c_str();
226 }
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000227
bsalomon@google.com706f6682012-10-23 14:53:55 +0000228 /** Returns a variable name that represents the position of the fragment in the FS. The position
229 is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
230 const char* fragmentPosition();
231
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000232 /** Returns the color of the destination pixel. This may be NULL if no effect advertised
233 that it will read the destination. */
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000234 const char* dstColor();
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000235
bsalomon@google.comc7818882013-03-20 19:19:53 +0000236 /**
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000237 * Interfaces used by GrGLProgram.
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000238 * TODO: These are used by GrGLProgram to insert a mode color filter. Remove these when the
239 * color filter is expressed as a GrEffect.
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000240 */
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000241 const SkString& getInputColor() const { return fInputColor; }
242 GrSLConstantVec getKnownColorValue() const { return fKnownColorValue; }
243 const SkString& getInputCoverage() const { return fInputCoverage; }
244 GrSLConstantVec getKnownCoverageValue() const { return fKnownCoverageValue; }
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000245
bsalomon@google.com504976e2013-05-09 13:45:02 +0000246 /**
247 * Adds code for effects. effectStages contains the effects to add. effectKeys[i] is the key
248 * generated from effectStages[i]. An entry in effectStages can be NULL, in which case it is
249 * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey then it is skipped.
250 * inOutFSColor specifies the input color to the first stage and is updated to be the
251 * output color of the last stage. fsInOutColorKnownValue specifies whether the input color
252 * has a known constant value and is updated to refer to the status of the output color.
253 * The handles to texture samplers for effectStage[i] are added to effectSamplerHandles[i]. The
254 * glEffects array is updated to contain the GrGLEffect generated for each entry in
255 * effectStages.
256 */
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000257 void emitEffects(const GrEffectStage* effectStages[],
bsalomon@google.com504976e2013-05-09 13:45:02 +0000258 const GrBackendEffectFactory::EffectKey effectKeys[],
259 int effectCnt,
260 SkString* inOutFSColor,
261 GrSLConstantVec* fsInOutColorKnownValue,
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000262 SkTArray<GrGLUniformManager::UniformHandle, true>* effectSamplerHandles[],
263 GrGLEffect* glEffects[]);
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000264
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000265 const char* getColorOutputName() const;
266 const char* enableSecondaryOutput();
267
bsalomon@google.com706f6682012-10-23 14:53:55 +0000268 GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000269 GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
270 return fDstCopyTopLeftUniform;
271 }
272 GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
273 return fDstCopyScaleUniform;
274 }
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000275 GrGLUniformManager::UniformHandle getColorUniform() const { return fColorUniform; }
276 GrGLUniformManager::UniformHandle getCoverageUniform() const { return fCoverageUniform; }
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000277 GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
278 return fDstCopySampler.fSamplerUniform;
279 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000280
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000281 /** Helper class used to build the vertex and geometry shaders. This functionality
282 is kept separate from the rest of GrGLShaderBuilder to allow for shaders programs
283 that only use the fragment shader. */
284 class VertexBuilder {
285 public:
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000286 VertexBuilder(GrGLShaderBuilder* parent, GrGpuGL* gpu, const GrGLProgramDesc&);
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000287
288 /**
289 * Called by GrGLEffects to add code to one of the shaders.
290 */
291 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
292 va_list args;
293 va_start(args, format);
294 fVSCode.appendf(format, args);
295 va_end(args);
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000296 }
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000297
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000298 void vsCodeAppend(const char* str) { fVSCode.append(str); }
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000299
300 /** Add a vertex attribute to the current program that is passed in from the vertex data.
301 Returns false if the attribute was already there, true otherwise. */
302 bool addAttribute(GrSLType type, const char* name);
303
304 /** Add a varying variable to the current program to pass values between vertex and fragment
305 shaders. If the last two parameters are non-NULL, they are filled in with the name
306 generated. */
307 void addVarying(GrSLType type,
308 const char* name,
309 const char** vsOutName = NULL,
310 const char** fsInName = NULL);
311
312 /** Returns a vertex attribute that represents the vertex position in the VS. This is the
313 pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
314 */
315 const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
316
317 /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
318 as positionAttribute() or it may not be. It depends upon whether the rendering code
319 specified explicit local coords or not in the GrDrawState. */
320 const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
321
322 /**
323 * Are explicit local coordinates provided as input to the vertex shader.
324 */
325 bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
326
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000327 bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
328 const SkString* getEffectAttributeName(int attributeIndex) const;
329
330 GrGLUniformManager::UniformHandle getViewMatrixUniform() const {
331 return fViewMatrixUniform;
332 }
333
334 bool compileAndAttachShaders(GrGLuint programId) const;
335 void bindProgramLocations(GrGLuint programId) const;
336
337 private:
338 GrGLShaderBuilder* fParent;
339 GrGpuGL* fGpu;
340 const GrGLProgramDesc& fDesc;
341 VarArray fVSAttrs;
342 VarArray fVSOutputs;
343 VarArray fGSInputs;
344 VarArray fGSOutputs;
345
346 SkString fVSCode;
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000347
348 struct AttributePair {
349 void set(int index, const SkString& name) {
350 fIndex = index; fName = name;
351 }
352 int fIndex;
353 SkString fName;
354 };
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000355 SkSTArray<10, AttributePair, true> fEffectAttributes;
356
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000357 GrGLUniformManager::UniformHandle fViewMatrixUniform;
358
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000359 GrGLShaderVar* fPositionVar;
360 GrGLShaderVar* fLocalCoordsVar;
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000361 };
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000362
363 /** Gets the vertex builder that is used to construct the vertex and geometry shaders.
364 It may be NULL if this shader program is only meant to have a fragment shader. */
365 VertexBuilder* getVertexBuilder() const { return fVertexBuilder.get(); }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000366
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000367 bool finish(GrGLuint* outProgramId);
bsalomon@google.com706f6682012-10-23 14:53:55 +0000368
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000369 const GrGLContextInfo& ctxInfo() const;
robertphillips@google.com13f181f2013-03-02 12:02:08 +0000370
bsalomon@google.com032b2212012-07-16 13:36:18 +0000371private:
bsalomon@google.com032b2212012-07-16 13:36:18 +0000372 void appendDecls(const VarArray&, SkString*) const;
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000373 void appendUniformDecls(ShaderVisibility, SkString*) const;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000374
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000375 bool compileAndAttachShaders(GrGLuint programId) const;
376 void bindProgramLocations(GrGLuint programId) const;
377
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000378 typedef GrGLUniformManager::BuilderUniform BuilderUniform;
379 GrGLUniformManager::BuilderUniformArray fUniforms;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000380
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000381private:
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000382 class CodeStage : public SkNoncopyable {
bsalomon@google.com504976e2013-05-09 13:45:02 +0000383 public:
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000384 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
bsalomon@google.com504976e2013-05-09 13:45:02 +0000385
386 bool inStageCode() const {
387 this->validate();
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000388 return NULL != fEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000389 }
390
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000391 const GrEffectStage* effectStage() const {
bsalomon@google.com504976e2013-05-09 13:45:02 +0000392 this->validate();
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000393 return fEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000394 }
395
396 int stageIndex() const {
skia.committer@gmail.com0f20a3f2013-05-10 07:01:04 +0000397 this->validate();
bsalomon@google.com504976e2013-05-09 13:45:02 +0000398 return fCurrentIndex;
399 }
400
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000401 class AutoStageRestore : public SkNoncopyable {
bsalomon@google.com504976e2013-05-09 13:45:02 +0000402 public:
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000403 AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000404 SkASSERT(NULL != codeStage);
bsalomon@google.com504976e2013-05-09 13:45:02 +0000405 fSavedIndex = codeStage->fCurrentIndex;
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000406 fSavedEffectStage = codeStage->fEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000407
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000408 if (NULL == newStage) {
bsalomon@google.com504976e2013-05-09 13:45:02 +0000409 codeStage->fCurrentIndex = -1;
410 } else {
411 codeStage->fCurrentIndex = codeStage->fNextIndex++;
412 }
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000413 codeStage->fEffectStage = newStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000414
415 fCodeStage = codeStage;
416 }
417 ~AutoStageRestore() {
418 fCodeStage->fCurrentIndex = fSavedIndex;
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000419 fCodeStage->fEffectStage = fSavedEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000420 }
421 private:
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000422 CodeStage* fCodeStage;
423 int fSavedIndex;
424 const GrEffectStage* fSavedEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000425 };
426 private:
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000427 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
428 int fNextIndex;
429 int fCurrentIndex;
430 const GrEffectStage* fEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000431 } fCodeStage;
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000432
bsalomon@google.com42eff162013-04-02 12:50:49 +0000433 /**
434 * Features that should only be enabled by GrGLShaderBuilder itself.
435 */
436 enum GLSLPrivateFeature {
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000437 kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
438 kEXTShaderFramebufferFetch_GLSLPrivateFeature,
439 kNVShaderFramebufferFetch_GLSLPrivateFeature,
bsalomon@google.com42eff162013-04-02 12:50:49 +0000440 };
441 bool enablePrivateFeature(GLSLPrivateFeature);
442
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000443 // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
444 // track the enables separately for each shader.
bsalomon@google.com42eff162013-04-02 12:50:49 +0000445 void addFSFeature(uint32_t featureBit, const char* extensionName);
446
bsalomon@google.com504976e2013-05-09 13:45:02 +0000447 // Generates a name for a variable. The generated string will be name prefixed by the prefix
448 // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
449 // generating stage code.
450 void nameVariable(SkString* out, char prefix, const char* name);
451
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000452 // Interpretation of DstReadKey when generating code
453 enum {
454 kNoDstRead_DstReadKey = 0,
455 kYesDstRead_DstReadKeyBit = 0x1, // Set if we do a dst-copy-read.
456 kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
457 kTopLeftOrigin_DstReadKeyBit = 0x4, // Set if dst-copy origin is top-left.
458 };
459
bsalomon@google.comb5158812013-05-13 18:50:25 +0000460 enum {
461 kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
462 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
463 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
464 };
465
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000466 GrGpuGL* fGpu;
bsalomon@google.com706f6682012-10-23 14:53:55 +0000467 GrGLUniformManager& fUniformManager;
bsalomon@google.com42eff162013-04-02 12:50:49 +0000468 uint32_t fFSFeaturesAddedMask;
bsalomon@google.com706f6682012-10-23 14:53:55 +0000469 SkString fFSFunctions;
bsalomon@google.com42eff162013-04-02 12:50:49 +0000470 SkString fFSExtensions;
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +0000471 VarArray fFSInputs;
472 VarArray fFSOutputs;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000473
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000474 SkString fFSCode;
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000475
bsalomon@google.com706f6682012-10-23 14:53:55 +0000476 bool fSetupFragPosition;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000477 TextureSampler fDstCopySampler;
478
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000479 SkString fInputColor;
480 GrSLConstantVec fKnownColorValue;
481 SkString fInputCoverage;
482 GrSLConstantVec fKnownCoverageValue;
483
484 bool fHasCustomColorOutput;
485 bool fHasSecondaryOutput;
486
bsalomon@google.com706f6682012-10-23 14:53:55 +0000487 GrGLUniformManager::UniformHandle fRTHeightUniform;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000488 GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform;
489 GrGLUniformManager::UniformHandle fDstCopyScaleUniform;
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000490 GrGLUniformManager::UniformHandle fColorUniform;
491 GrGLUniformManager::UniformHandle fCoverageUniform;
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +0000492
bsalomon@google.comb5158812013-05-13 18:50:25 +0000493 bool fTopLeftFragPosRead;
494
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000495 SkAutoTDelete<VertexBuilder> fVertexBuilder;
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000496};
497
498#endif