blob: 4c43fc36c3947cb1c9abddb73144a22cd760688f [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"
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000016#include "gl/GrGLProgramEffects.h"
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000017#include "gl/GrGLSL.h"
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000018#include "gl/GrGLUniformManager.h"
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000019
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000020#include <stdarg.h>
21
bsalomon@google.comad5e9372012-07-11 18:11:27 +000022class GrGLContextInfo;
bsalomon@google.comc7818882013-03-20 19:19:53 +000023class GrEffectStage;
bsalomon@google.com26e18b52013-03-29 19:22:36 +000024class GrGLProgramDesc;
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +000025
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000026/**
bsalomon@google.comeb715c82012-07-11 15:03:31 +000027 Contains all the incremental state of a shader as it is being built,as well as helpers to
28 manipulate that state.
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000029*/
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000030class GrGLShaderBuilder {
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000031public:
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +000032 typedef GrTAllocator<GrGLShaderVar> VarArray;
bsalomon@google.com77af6802013-10-02 13:04:56 +000033 typedef GrBackendEffectFactory::EffectKey EffectKey;
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +000034 typedef GrGLProgramEffects::TextureSampler TextureSampler;
35 typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray;
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000036 typedef GrGLUniformManager::BuilderUniform BuilderUniform;
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000037
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +000038 enum ShaderVisibility {
39 kVertex_Visibility = 0x1,
40 kGeometry_Visibility = 0x2,
41 kFragment_Visibility = 0x4,
bsalomon@google.comeb715c82012-07-11 15:03:31 +000042 };
43
commit-bot@chromium.org261dc562013-10-04 15:42:56 +000044 GrGLShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
45 virtual ~GrGLShaderBuilder() {}
tomhudson@google.comf9ad8862012-05-11 20:38:48 +000046
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000047 /**
bsalomon@google.com42eff162013-04-02 12:50:49 +000048 * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
49 * if code is added that uses one of these features without calling enableFeature()
50 */
51 enum GLSLFeature {
52 kStandardDerivatives_GLSLFeature = 0,
53
54 kLastGLSLFeature = kStandardDerivatives_GLSLFeature
55 };
56
57 /**
58 * If the feature is supported then true is returned and any necessary #extension declarations
59 * are added to the shaders. If the feature is not supported then false will be returned.
60 */
61 bool enableFeature(GLSLFeature);
62
63 /**
commit-bot@chromium.org5a02cb42013-08-30 20:17:31 +000064 * Called by GrGLEffects to add code the fragment shader.
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000065 */
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000066 void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
67 va_list args;
68 va_start(args, format);
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +000069 fFSCode.appendf(format, args);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000070 va_end(args);
71 }
72
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +000073 void fsCodeAppend(const char* str) { fFSCode.append(str); }
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000074
bsalomon@google.comdbe49f72012-11-05 16:36:02 +000075 /** Appends a 2D texture sample with projection if necessary. coordType must either be Vec2f or
76 Vec3f. The latter is interpreted as projective texture coords. The vec length and swizzle
77 order of the result depends on the GrTextureAccess associated with the TextureSampler. */
bsalomon@google.com868a8e72012-08-30 19:11:34 +000078 void appendTextureLookup(SkString* out,
bsalomon@google.comf06df1b2012-09-06 20:22:31 +000079 const TextureSampler&,
bsalomon@google.comdbe49f72012-11-05 16:36:02 +000080 const char* coordName,
bsalomon@google.com868a8e72012-08-30 19:11:34 +000081 GrSLType coordType = kVec2f_GrSLType) const;
tomhudson@google.com52598142012-05-24 17:44:30 +000082
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +000083 /** Version of above that appends the result to the fragment shader code instead.*/
84 void fsAppendTextureLookup(const TextureSampler&,
85 const char* coordName,
86 GrSLType coordType = kVec2f_GrSLType);
bsalomon@google.comf910d3b2013-03-07 17:06:57 +000087
88
bsalomon@google.com2d8edaf2012-09-07 14:47:31 +000089 /** Does the work of appendTextureLookup and modulates the result by modulation. The result is
90 always a vec4. modulation and the swizzle specified by TextureSampler must both be vec4 or
91 float. If modulation is "" or NULL it this function acts as though appendTextureLookup were
92 called. */
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +000093 void fsAppendTextureLookupAndModulate(const char* modulation,
94 const TextureSampler&,
95 const char* coordName,
96 GrSLType coordType = kVec2f_GrSLType);
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +000097
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +000098 /** Emits a helper function outside of main() in the fragment shader. */
99 void fsEmitFunction(GrSLType returnType,
100 const char* name,
101 int argCnt,
102 const GrGLShaderVar* args,
103 const char* body,
104 SkString* outName);
bsalomon@google.coma1bf0ff2012-08-07 17:36:29 +0000105
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000106 typedef uint8_t DstReadKey;
bsalomon@google.comb5158812013-05-13 18:50:25 +0000107 typedef uint8_t FragPosKey;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000108
109 /** Returns a key for adding code to read the copy-of-dst color in service of effects that
110 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 +0000111 copy read at all (in which case this function should not be called). */
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000112 static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&);
113
bsalomon@google.comb5158812013-05-13 18:50:25 +0000114 /** Returns a key for reading the fragment location. This should only be called if there is an
115 effect that will requires the fragment position. If the fragment position is not required,
116 the key is 0. */
117 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&);
118
bsalomon@google.com6d003d12012-09-11 15:45:20 +0000119 /** If texture swizzling is available using tex parameters then it is preferred over mangling
120 the generated shader code. This potentially allows greater reuse of cached shaders. */
121 static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps);
122
bsalomon@google.com706f6682012-10-23 14:53:55 +0000123 /** 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 +0000124 visibility is a bitfield of ShaderVisibility values indicating from which shaders the
125 uniform should be accessible. At least one bit must be set. Geometry shader uniforms are not
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000126 supported at this time. The actual uniform name will be mangled. If outName is not NULL then
127 it will refer to the final uniform name after return. Use the addUniformArray variant to add
128 an array of uniforms.
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000129 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000130 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility,
131 GrSLType type,
132 const char* name,
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000133 const char** outName = NULL) {
134 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName);
135 }
136 GrGLUniformManager::UniformHandle addUniformArray(uint32_t visibility,
137 GrSLType type,
138 const char* name,
139 int arrayCount,
140 const char** outName = NULL);
bsalomon@google.com032b2212012-07-16 13:36:18 +0000141
commit-bot@chromium.org7425c122013-08-14 18:14:19 +0000142 const GrGLShaderVar& getUniformVariable(GrGLUniformManager::UniformHandle u) const {
143 return fUniformManager.getBuilderUniform(fUniforms, u).fVariable;
144 }
bsalomon@google.com032b2212012-07-16 13:36:18 +0000145
146 /**
bsalomon@google.com706f6682012-10-23 14:53:55 +0000147 * Shortcut for getUniformVariable(u).c_str()
bsalomon@google.com032b2212012-07-16 13:36:18 +0000148 */
bsalomon@google.comdbbc4e22012-07-25 17:48:39 +0000149 const char* getUniformCStr(GrGLUniformManager::UniformHandle u) const {
bsalomon@google.com032b2212012-07-16 13:36:18 +0000150 return this->getUniformVariable(u).c_str();
151 }
tomhudson@google.com242ed6f2012-05-30 17:38:57 +0000152
bsalomon@google.com77af6802013-10-02 13:04:56 +0000153 /**
154 * This returns a variable name to access the 2D, perspective correct version of the coords in
155 * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
156 * perspective divide into the fragment shader (xy / z) to convert them to 2D.
157 */
158 SkString ensureFSCoords2D(const TransformedCoordsArray&, int index);
159
bsalomon@google.com706f6682012-10-23 14:53:55 +0000160 /** Returns a variable name that represents the position of the fragment in the FS. The position
161 is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
162 const char* fragmentPosition();
163
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000164 /** Returns the color of the destination pixel. This may be NULL if no effect advertised
165 that it will read the destination. */
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000166 const char* dstColor();
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000167
bsalomon@google.comc7818882013-03-20 19:19:53 +0000168 /**
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000169 * Interfaces used by GrGLProgram.
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000170 * TODO: These are used by GrGLProgram to insert a mode color filter. Remove these when the
171 * color filter is expressed as a GrEffect.
bsalomon@google.com34cccde2013-01-04 18:34:30 +0000172 */
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000173 const SkString& getInputColor() const {
174 SkASSERT(fInputColor.isEmpty() != (kNone_GrSLConstantVec == fKnownColorValue));
175 return fInputColor;
176 }
177 GrSLConstantVec getKnownColorValue() const {
178 SkASSERT(fInputColor.isEmpty() != (kNone_GrSLConstantVec == fKnownColorValue));
179 return fKnownColorValue;
180 }
181 const SkString& getInputCoverage() const {
182 SkASSERT(fInputCoverage.isEmpty() != (kNone_GrSLConstantVec == fKnownCoverageValue));
183 return fInputCoverage;
184 }
185 GrSLConstantVec getKnownCoverageValue() const {
186 SkASSERT(fInputCoverage.isEmpty() != (kNone_GrSLConstantVec == fKnownCoverageValue));
187 return fKnownCoverageValue;
188 }
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000189
bsalomon@google.com504976e2013-05-09 13:45:02 +0000190 /**
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000191 * Adds code for effects and returns a GrGLProgramEffects* object. The caller is responsible for
192 * deleting it when finished. effectStages contains the effects to add. effectKeys[i] is the key
193 * generated from effectStages[i]. inOutFSColor specifies the input color to the first stage and
194 * is updated to be the output color of the last stage. fsInOutColorKnownValue specifies whether
195 * the input color has a known constant value and is updated to refer to the status of the
196 * output color. The handles to texture samplers for effectStage[i] are added to
197 * effectSamplerHandles[i].
bsalomon@google.com504976e2013-05-09 13:45:02 +0000198 */
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000199 virtual GrGLProgramEffects* createAndEmitEffects(const GrEffectStage* effectStages[],
200 const EffectKey effectKeys[],
201 int effectCnt,
202 SkString* inOutFSColor,
203 GrSLConstantVec* fsInOutColorKnownValue) = 0;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000204
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000205 const char* getColorOutputName() const;
206 const char* enableSecondaryOutput();
207
bsalomon@google.com706f6682012-10-23 14:53:55 +0000208 GrGLUniformManager::UniformHandle getRTHeightUniform() const { return fRTHeightUniform; }
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000209 GrGLUniformManager::UniformHandle getDstCopyTopLeftUniform() const {
210 return fDstCopyTopLeftUniform;
211 }
212 GrGLUniformManager::UniformHandle getDstCopyScaleUniform() const {
213 return fDstCopyScaleUniform;
214 }
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000215 GrGLUniformManager::UniformHandle getColorUniform() const { return fColorUniform; }
216 GrGLUniformManager::UniformHandle getCoverageUniform() const { return fCoverageUniform; }
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000217 GrGLUniformManager::UniformHandle getDstCopySamplerUniform() const {
commit-bot@chromium.org3390b9a2013-10-03 15:17:58 +0000218 return fDstCopySamplerUniform;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000219 }
commit-bot@chromium.orgff6ea262013-03-12 12:26:08 +0000220
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000221 bool finish(GrGLuint* outProgramId);
bsalomon@google.com706f6682012-10-23 14:53:55 +0000222
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000223 const GrGLContextInfo& ctxInfo() const;
robertphillips@google.com13f181f2013-03-02 12:02:08 +0000224
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000225protected:
226 GrGpuGL* gpu() const { return fGpu; }
227
228 void setInputColor(const char* inputColor) { fInputColor = inputColor; }
229 void setInputCoverage(const char* inputCoverage) { fInputCoverage = inputCoverage; }
230
231 /** Add input/output variable declarations (i.e. 'varying') to the fragment shader. */
232 GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); }
233
234 // Generates a name for a variable. The generated string will be name prefixed by the prefix
235 // char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're
236 // generating stage code.
237 void nameVariable(SkString* out, char prefix, const char* name);
238
239 // Helper for emitEffects().
240 void createAndEmitEffects(GrGLProgramEffectsBuilder*,
241 const GrEffectStage* effectStages[],
242 const EffectKey effectKeys[],
243 int effectCnt,
244 SkString* inOutFSColor,
245 GrSLConstantVec* fsInOutColorKnownValue);
246
247 virtual bool compileAndAttachShaders(GrGLuint programId) const;
248 virtual void bindProgramLocations(GrGLuint programId) const;
249
bsalomon@google.com032b2212012-07-16 13:36:18 +0000250 void appendDecls(const VarArray&, SkString*) const;
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000251 void appendUniformDecls(ShaderVisibility, SkString*) const;
bsalomon@google.com032b2212012-07-16 13:36:18 +0000252
bsalomon@google.comad5e9372012-07-11 18:11:27 +0000253private:
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000254 class CodeStage : public SkNoncopyable {
bsalomon@google.com504976e2013-05-09 13:45:02 +0000255 public:
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000256 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {}
bsalomon@google.com504976e2013-05-09 13:45:02 +0000257
258 bool inStageCode() const {
259 this->validate();
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000260 return NULL != fEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000261 }
262
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000263 const GrEffectStage* effectStage() const {
bsalomon@google.com504976e2013-05-09 13:45:02 +0000264 this->validate();
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000265 return fEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000266 }
267
268 int stageIndex() const {
skia.committer@gmail.com0f20a3f2013-05-10 07:01:04 +0000269 this->validate();
bsalomon@google.com504976e2013-05-09 13:45:02 +0000270 return fCurrentIndex;
271 }
272
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +0000273 class AutoStageRestore : public SkNoncopyable {
bsalomon@google.com504976e2013-05-09 13:45:02 +0000274 public:
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000275 AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) {
tfarina@chromium.orgf6de4752013-08-17 00:02:59 +0000276 SkASSERT(NULL != codeStage);
bsalomon@google.com504976e2013-05-09 13:45:02 +0000277 fSavedIndex = codeStage->fCurrentIndex;
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000278 fSavedEffectStage = codeStage->fEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000279
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000280 if (NULL == newStage) {
bsalomon@google.com504976e2013-05-09 13:45:02 +0000281 codeStage->fCurrentIndex = -1;
282 } else {
283 codeStage->fCurrentIndex = codeStage->fNextIndex++;
284 }
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000285 codeStage->fEffectStage = newStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000286
287 fCodeStage = codeStage;
288 }
289 ~AutoStageRestore() {
290 fCodeStage->fCurrentIndex = fSavedIndex;
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000291 fCodeStage->fEffectStage = fSavedEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000292 }
293 private:
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000294 CodeStage* fCodeStage;
295 int fSavedIndex;
296 const GrEffectStage* fSavedEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000297 };
298 private:
commit-bot@chromium.orga4acf122013-09-30 15:13:58 +0000299 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); }
300 int fNextIndex;
301 int fCurrentIndex;
302 const GrEffectStage* fEffectStage;
bsalomon@google.com504976e2013-05-09 13:45:02 +0000303 } fCodeStage;
bsalomon@google.com777c3aa2012-07-25 20:58:20 +0000304
bsalomon@google.com42eff162013-04-02 12:50:49 +0000305 /**
306 * Features that should only be enabled by GrGLShaderBuilder itself.
307 */
308 enum GLSLPrivateFeature {
bsalomon@google.com6b0cf022013-05-03 13:35:14 +0000309 kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1,
310 kEXTShaderFramebufferFetch_GLSLPrivateFeature,
311 kNVShaderFramebufferFetch_GLSLPrivateFeature,
bsalomon@google.com42eff162013-04-02 12:50:49 +0000312 };
313 bool enablePrivateFeature(GLSLPrivateFeature);
314
commit-bot@chromium.org74a3a212013-08-30 19:43:59 +0000315 // If we ever have VS/GS features we can expand this to take a bitmask of ShaderVisibility and
316 // track the enables separately for each shader.
bsalomon@google.com42eff162013-04-02 12:50:49 +0000317 void addFSFeature(uint32_t featureBit, const char* extensionName);
318
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000319 // Interpretation of DstReadKey when generating code
320 enum {
321 kNoDstRead_DstReadKey = 0,
322 kYesDstRead_DstReadKeyBit = 0x1, // Set if we do a dst-copy-read.
323 kUseAlphaConfig_DstReadKeyBit = 0x2, // Set if dst-copy config is alpha only.
324 kTopLeftOrigin_DstReadKeyBit = 0x4, // Set if dst-copy origin is top-left.
325 };
326
bsalomon@google.comb5158812013-05-13 18:50:25 +0000327 enum {
328 kNoFragPosRead_FragPosKey = 0, // The fragment positition will not be needed.
329 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to top-left.
330 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to bottom-left.
331 };
332
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000333 GrGpuGL* fGpu;
334 GrGLUniformManager& fUniformManager;
335 uint32_t fFSFeaturesAddedMask;
336 SkString fFSFunctions;
337 SkString fFSExtensions;
338 VarArray fFSInputs;
339 VarArray fFSOutputs;
340 GrGLUniformManager::BuilderUniformArray fUniforms;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000341
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000342 SkString fFSCode;
bsalomon@google.comf910d3b2013-03-07 17:06:57 +0000343
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000344 bool fSetupFragPosition;
345 GrGLUniformManager::UniformHandle fDstCopySamplerUniform;
bsalomon@google.com26e18b52013-03-29 19:22:36 +0000346
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000347 SkString fInputColor;
348 GrSLConstantVec fKnownColorValue;
349 SkString fInputCoverage;
350 GrSLConstantVec fKnownCoverageValue;
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000351
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000352 bool fHasCustomColorOutput;
353 bool fHasSecondaryOutput;
commit-bot@chromium.org410552a2013-09-30 15:30:27 +0000354
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000355 GrGLUniformManager::UniformHandle fRTHeightUniform;
356 GrGLUniformManager::UniformHandle fDstCopyTopLeftUniform;
357 GrGLUniformManager::UniformHandle fDstCopyScaleUniform;
358 GrGLUniformManager::UniformHandle fColorUniform;
359 GrGLUniformManager::UniformHandle fCoverageUniform;
bsalomon@google.com34bcb9f2012-08-28 18:20:18 +0000360
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000361 bool fTopLeftFragPosRead;
362};
bsalomon@google.comb5158812013-05-13 18:50:25 +0000363
commit-bot@chromium.org261dc562013-10-04 15:42:56 +0000364////////////////////////////////////////////////////////////////////////////////
365
366class GrGLFullShaderBuilder : public GrGLShaderBuilder {
367public:
368 GrGLFullShaderBuilder(GrGpuGL*, GrGLUniformManager&, const GrGLProgramDesc&);
369
370 /**
371 * Called by GrGLEffects to add code to one of the shaders.
372 */
373 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) {
374 va_list args;
375 va_start(args, format);
376 fVSCode.appendf(format, args);
377 va_end(args);
378 }
379
380 void vsCodeAppend(const char* str) { fVSCode.append(str); }
381
382 /** Add a vertex attribute to the current program that is passed in from the vertex data.
383 Returns false if the attribute was already there, true otherwise. */
384 bool addAttribute(GrSLType type, const char* name);
385
386 /** Add a varying variable to the current program to pass values between vertex and fragment
387 shaders. If the last two parameters are non-NULL, they are filled in with the name
388 generated. */
389 void addVarying(GrSLType type,
390 const char* name,
391 const char** vsOutName = NULL,
392 const char** fsInName = NULL);
393
394 /** Returns a vertex attribute that represents the vertex position in the VS. This is the
395 pre-matrix position and is commonly used by effects to compute texture coords via a matrix.
396 */
397 const GrGLShaderVar& positionAttribute() const { return *fPositionVar; }
398
399 /** Returns a vertex attribute that represents the local coords in the VS. This may be the same
400 as positionAttribute() or it may not be. It depends upon whether the rendering code
401 specified explicit local coords or not in the GrDrawState. */
402 const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar; }
403
404 /**
405 * Are explicit local coordinates provided as input to the vertex shader.
406 */
407 bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVar); }
408
409 bool addEffectAttribute(int attributeIndex, GrSLType type, const SkString& name);
410 const SkString* getEffectAttributeName(int attributeIndex) const;
411
412 virtual GrGLProgramEffects* createAndEmitEffects(
413 const GrEffectStage* effectStages[],
414 const EffectKey effectKeys[],
415 int effectCnt,
416 SkString* inOutFSColor,
417 GrSLConstantVec* fsInOutColorKnownValue) SK_OVERRIDE;
418
419 GrGLUniformManager::UniformHandle getViewMatrixUniform() const {
420 return fViewMatrixUniform;
421 }
422
423protected:
424 virtual bool compileAndAttachShaders(GrGLuint programId) const SK_OVERRIDE;
425 virtual void bindProgramLocations(GrGLuint programId) const SK_OVERRIDE;
426
427private:
428 const GrGLProgramDesc& fDesc;
429 VarArray fVSAttrs;
430 VarArray fVSOutputs;
431 VarArray fGSInputs;
432 VarArray fGSOutputs;
433
434 SkString fVSCode;
435
436 struct AttributePair {
437 void set(int index, const SkString& name) {
438 fIndex = index; fName = name;
439 }
440 int fIndex;
441 SkString fName;
442 };
443 SkSTArray<10, AttributePair, true> fEffectAttributes;
444
445 GrGLUniformManager::UniformHandle fViewMatrixUniform;
446
447 GrGLShaderVar* fPositionVar;
448 GrGLShaderVar* fLocalCoordsVar;
449
450 typedef GrGLShaderBuilder INHERITED;
tomhudson@google.comf9ad8862012-05-11 20:38:48 +0000451};
452
453#endif