| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef GrGLShaderBuilder_DEFINED | 8 #ifndef GrGLShaderBuilder_DEFINED |
| 9 #define GrGLShaderBuilder_DEFINED | 9 #define GrGLShaderBuilder_DEFINED |
| 10 | 10 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 uint32_t configComponentMask, | 64 uint32_t configComponentMask, |
| 65 const char* swizzle, | 65 const char* swizzle, |
| 66 int idx) { | 66 int idx) { |
| 67 SkASSERT(!this->isInitialized()); | 67 SkASSERT(!this->isInitialized()); |
| 68 SkASSERT(0 != configComponentMask); | 68 SkASSERT(0 != configComponentMask); |
| 69 SkASSERT(!fSamplerUniform.isValid()); | 69 SkASSERT(!fSamplerUniform.isValid()); |
| 70 | 70 |
| 71 SkASSERT(NULL != builder); | 71 SkASSERT(NULL != builder); |
| 72 SkString name; | 72 SkString name; |
| 73 name.printf("Sampler%d", idx); | 73 name.printf("Sampler%d", idx); |
| 74 fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_S
haderType, | 74 fSamplerUniform = builder->addUniform(GrGLShaderBuilder::kFragment_V
isibility, |
| 75 kSampler2D_GrSLType, | 75 kSampler2D_GrSLType, |
| 76 name.c_str()); | 76 name.c_str()); |
| 77 SkASSERT(fSamplerUniform.isValid()); | 77 SkASSERT(fSamplerUniform.isValid()); |
| 78 | 78 |
| 79 fConfigComponentMask = configComponentMask; | 79 fConfigComponentMask = configComponentMask; |
| 80 memcpy(fSwizzle, swizzle, 4); | 80 memcpy(fSwizzle, swizzle, 4); |
| 81 } | 81 } |
| 82 | 82 |
| 83 void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int
idx) { | 83 void init(GrGLShaderBuilder* builder, const GrTextureAccess* access, int
idx) { |
| 84 SkASSERT(NULL != access); | 84 SkASSERT(NULL != access); |
| 85 this->init(builder, | 85 this->init(builder, |
| 86 GrPixelConfigComponentMask(access->getTexture()->config()
), | 86 GrPixelConfigComponentMask(access->getTexture()->config()
), |
| 87 access->getSwizzle(), | 87 access->getSwizzle(), |
| 88 idx); | 88 idx); |
| 89 } | 89 } |
| 90 | 90 |
| 91 uint32_t fConfigComponentMask; | 91 uint32_t fConfigComponentMask; |
| 92 char fSwizzle[5]; | 92 char fSwizzle[5]; |
| 93 GrGLUniformManager::UniformHandle fSamplerUniform; | 93 GrGLUniformManager::UniformHandle fSamplerUniform; |
| 94 | 94 |
| 95 friend class GrGLShaderBuilder; // to call init(). | 95 friend class GrGLShaderBuilder; // to call init(). |
| 96 }; | 96 }; |
| 97 | 97 |
| 98 typedef SkTArray<TextureSampler> TextureSamplerArray; | 98 typedef SkTArray<TextureSampler> TextureSamplerArray; |
| 99 | 99 |
| 100 enum ShaderType { | 100 enum ShaderVisibility { |
| 101 kVertex_ShaderType = 0x1, | 101 kVertex_Visibility = 0x1, |
| 102 kGeometry_ShaderType = 0x2, | 102 kGeometry_Visibility = 0x2, |
| 103 kFragment_ShaderType = 0x4, | 103 kFragment_Visibility = 0x4, |
| 104 }; | 104 }; |
| 105 | 105 |
| 106 GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLPro
gramDesc&); | 106 GrGLShaderBuilder(const GrGLContextInfo&, GrGLUniformManager&, const GrGLPro
gramDesc&); |
| 107 | 107 |
| 108 /** | 108 /** |
| 109 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile | 109 * 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 enableFe
ature() | 110 * if code is added that uses one of these features without calling enableFe
ature() |
| 111 */ | 111 */ |
| 112 enum GLSLFeature { | 112 enum GLSLFeature { |
| 113 kStandardDerivatives_GLSLFeature = 0, | 113 kStandardDerivatives_GLSLFeature = 0, |
| 114 | 114 |
| 115 kLastGLSLFeature = kStandardDerivatives_GLSLFeature | 115 kLastGLSLFeature = kStandardDerivatives_GLSLFeature |
| 116 }; | 116 }; |
| 117 | 117 |
| 118 /** | 118 /** |
| 119 * If the feature is supported then true is returned and any necessary #exte
nsion declarations | 119 * If the feature is supported then true is returned and any necessary #exte
nsion declarations |
| 120 * are added to the shaders. If the feature is not supported then false will
be returned. | 120 * are added to the shaders. If the feature is not supported then false will
be returned. |
| 121 */ | 121 */ |
| 122 bool enableFeature(GLSLFeature); | 122 bool enableFeature(GLSLFeature); |
| 123 | 123 |
| 124 /** | 124 /** |
| 125 * Called by GrGLEffects to add code to one of the shaders. | 125 * Called by GrGLEffects to add code to one of the shaders. |
| 126 */ | 126 */ |
| 127 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | 127 void vsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
| 128 va_list args; | 128 va_list args; |
| 129 va_start(args, format); | 129 va_start(args, format); |
| 130 this->codeAppendf(kVertex_ShaderType, format, args); | 130 fVSCode.appendf(format, args); |
| 131 va_end(args); | 131 va_end(args); |
| 132 } | 132 } |
| 133 | 133 |
| 134 void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | 134 void gsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
| 135 va_list args; | 135 va_list args; |
| 136 va_start(args, format); | 136 va_start(args, format); |
| 137 this->codeAppendf(kGeometry_ShaderType, format, args); | 137 fGSCode.appendf(format, args); |
| 138 va_end(args); | 138 va_end(args); |
| 139 } | 139 } |
| 140 | 140 |
| 141 void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { | 141 void fsCodeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { |
| 142 va_list args; | 142 va_list args; |
| 143 va_start(args, format); | 143 va_start(args, format); |
| 144 this->codeAppendf(kFragment_ShaderType, format, args); | 144 fFSCode.appendf(format, args); |
| 145 va_end(args); | 145 va_end(args); |
| 146 } | 146 } |
| 147 | 147 |
| 148 void vsCodeAppend(const char* str) { this->codeAppend(kVertex_ShaderType, st
r); } | 148 void vsCodeAppend(const char* str) { fVSCode.append(str); } |
| 149 void gsCodeAppend(const char* str) { this->codeAppend(kGeometry_ShaderType,
str); } | 149 void gsCodeAppend(const char* str) { fGSCode.append(str); } |
| 150 void fsCodeAppend(const char* str) { this->codeAppend(kFragment_ShaderType,
str); } | 150 void fsCodeAppend(const char* str) { fFSCode.append(str); } |
| 151 | 151 |
| 152 /** Appends a 2D texture sample with projection if necessary. coordType must
either be Vec2f or | 152 /** 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 l
ength and swizzle | 153 Vec3f. The latter is interpreted as projective texture coords. The vec l
ength and swizzle |
| 154 order of the result depends on the GrTextureAccess associated with the T
extureSampler. */ | 154 order of the result depends on the GrTextureAccess associated with the T
extureSampler. */ |
| 155 void appendTextureLookup(SkString* out, | 155 void appendTextureLookup(SkString* out, |
| 156 const TextureSampler&, | 156 const TextureSampler&, |
| 157 const char* coordName, | 157 const char* coordName, |
| 158 GrSLType coordType = kVec2f_GrSLType) const; | 158 GrSLType coordType = kVec2f_GrSLType) const; |
| 159 | 159 |
| 160 /** Version of above that appends the result to the shader code rather than
an SkString. | 160 /** Version of above that appends the result to the fragment shader code ins
tead.*/ |
| 161 Currently the shader type must be kFragment */ | 161 void fsAppendTextureLookup(const TextureSampler&, |
| 162 void appendTextureLookup(ShaderType, | 162 const char* coordName, |
| 163 const TextureSampler&, | 163 GrSLType coordType = kVec2f_GrSLType); |
| 164 const char* coordName, | |
| 165 GrSLType coordType = kVec2f_GrSLType); | |
| 166 | 164 |
| 167 | 165 |
| 168 /** Does the work of appendTextureLookup and modulates the result by modulat
ion. The result is | 166 /** Does the work of appendTextureLookup and modulates the result by modulat
ion. The result is |
| 169 always a vec4. modulation and the swizzle specified by TextureSampler mu
st both be vec4 or | 167 always a vec4. modulation and the swizzle specified by TextureSampler mu
st both be vec4 or |
| 170 float. If modulation is "" or NULL it this function acts as though appen
dTextureLookup were | 168 float. If modulation is "" or NULL it this function acts as though appen
dTextureLookup were |
| 171 called. */ | 169 called. */ |
| 172 void appendTextureLookupAndModulate(ShaderType, | 170 void fsAppendTextureLookupAndModulate(const char* modulation, |
| 173 const char* modulation, | 171 const TextureSampler&, |
| 174 const TextureSampler&, | 172 const char* coordName, |
| 175 const char* coordName, | 173 GrSLType coordType = kVec2f_GrSLType); |
| 176 GrSLType coordType = kVec2f_GrSLType); | |
| 177 | 174 |
| 178 /** Emits a helper function outside of main(). Currently ShaderType must be | 175 /** Emits a helper function outside of main() in the fragment shader. */ |
| 179 kFragment_ShaderType. */ | 176 void fsEmitFunction(GrSLType returnType, |
| 180 void emitFunction(ShaderType shader, | 177 const char* name, |
| 181 GrSLType returnType, | 178 int argCnt, |
| 182 const char* name, | 179 const GrGLShaderVar* args, |
| 183 int argCnt, | 180 const char* body, |
| 184 const GrGLShaderVar* args, | 181 SkString* outName); |
| 185 const char* body, | |
| 186 SkString* outName); | |
| 187 | 182 |
| 188 /** Generates a EffectKey for the shader code based on the texture access pa
rameters and the | 183 /** Generates a EffectKey for the shader code based on the texture access pa
rameters and the |
| 189 capabilities of the GL context. This is useful for keying the shader pr
ograms that may | 184 capabilities of the GL context. This is useful for keying the shader pr
ograms that may |
| 190 have multiple representations, based on the type/format of textures used
. */ | 185 have multiple representations, based on the type/format of textures used
. */ |
| 191 static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTexture
Access&, | 186 static GrBackendEffectFactory::EffectKey KeyForTextureAccess(const GrTexture
Access&, |
| 192 const GrGLCaps&
); | 187 const GrGLCaps&
); |
| 193 | 188 |
| 194 typedef uint8_t DstReadKey; | 189 typedef uint8_t DstReadKey; |
| 195 typedef uint8_t FragPosKey; | 190 typedef uint8_t FragPosKey; |
| 196 | 191 |
| 197 /** Returns a key for adding code to read the copy-of-dst color in service
of effects that | 192 /** Returns a key for adding code to read the copy-of-dst color in service
of effects that |
| 198 require reading the dst. It must not return 0 because 0 indicates that
there is no dst | 193 require reading the dst. It must not return 0 because 0 indicates that
there is no dst |
| 199 copy read at all (in which case this function should not be called). */ | 194 copy read at all (in which case this function should not be called). */ |
| 200 static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&); | 195 static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&); |
| 201 | 196 |
| 202 /** Returns a key for reading the fragment location. This should only be cal
led if there is an | 197 /** Returns a key for reading the fragment location. This should only be cal
led if there is an |
| 203 effect that will requires the fragment position. If the fragment positio
n is not required, | 198 effect that will requires the fragment position. If the fragment positio
n is not required, |
| 204 the key is 0. */ | 199 the key is 0. */ |
| 205 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const Gr
GLCaps&); | 200 static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const Gr
GLCaps&); |
| 206 | 201 |
| 207 /** If texture swizzling is available using tex parameters then it is prefer
red over mangling | 202 /** If texture swizzling is available using tex parameters then it is prefer
red over mangling |
| 208 the generated shader code. This potentially allows greater reuse of cach
ed shaders. */ | 203 the generated shader code. This potentially allows greater reuse of cach
ed shaders. */ |
| 209 static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCa
ps& caps); | 204 static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCa
ps& caps); |
| 210 | 205 |
| 211 /** Add a uniform variable to the current program, that has visibility in on
e or more shaders. | 206 /** Add a uniform variable to the current program, that has visibility in on
e or more shaders. |
| 212 visibility is a bitfield of ShaderType values indicating from which shad
ers the uniform | 207 visibility is a bitfield of ShaderVisibility values indicating from whic
h shaders the |
| 213 should be accessible. At least one bit must be set. Geometry shader unif
orms are not | 208 uniform should be accessible. At least one bit must be set. Geometry sha
der uniforms are not |
| 214 supported at this time. The actual uniform name will be mangled. If outN
ame is not NULL then | 209 supported at this time. The actual uniform name will be mangled. If outN
ame is not NULL then |
| 215 it will refer to the final uniform name after return. Use the addUniform
Array variant to add | 210 it will refer to the final uniform name after return. Use the addUniform
Array variant to add |
| 216 an array of uniforms. | 211 an array of uniforms. |
| 217 */ | 212 */ |
| 218 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility, | 213 GrGLUniformManager::UniformHandle addUniform(uint32_t visibility, |
| 219 GrSLType type, | 214 GrSLType type, |
| 220 const char* name, | 215 const char* name, |
| 221 const char** outName = NULL) { | 216 const char** outName = NULL) { |
| 222 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); | 217 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); |
| 223 } | 218 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 */ | 268 */ |
| 274 bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVa
r); } | 269 bool hasExplicitLocalCoords() const { return (fLocalCoordsVar != fPositionVa
r); } |
| 275 | 270 |
| 276 /** | 271 /** |
| 277 * Interfaces used by GrGLProgram. | 272 * Interfaces used by GrGLProgram. |
| 278 * TODO: Hide these from the GrEffects using friend or splitting this into t
wo related classes. | 273 * TODO: Hide these from the GrEffects using friend or splitting this into t
wo related classes. |
| 279 * Also, GrGLProgram's shader string construction should be moved to this cl
ass. | 274 * Also, GrGLProgram's shader string construction should be moved to this cl
ass. |
| 280 */ | 275 */ |
| 281 | 276 |
| 282 /** Called after building is complete to get the final shader string. */ | 277 /** Called after building is complete to get the final shader string. */ |
| 283 void getShader(ShaderType, SkString*) const; | 278 void vsGetShader(SkString*) const; |
| 279 void gsGetShader(SkString*) const; |
| 280 void fsGetShader(SkString*) const; |
| 284 | 281 |
| 285 /** | 282 /** |
| 286 * Adds code for effects. effectStages contains the effects to add. effectKe
ys[i] is the key | 283 * Adds code for effects. effectStages contains the effects to add. effectKe
ys[i] is the key |
| 287 * generated from effectStages[i]. An entry in effectStages can be NULL, in
which case it is | 284 * generated from effectStages[i]. An entry in effectStages can be NULL, in
which case it is |
| 288 * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey th
en it is skipped. | 285 * skipped. Moreover, if the corresponding key is GrGLEffect::NoEffectKey th
en it is skipped. |
| 289 * inOutFSColor specifies the input color to the first stage and is updated
to be the | 286 * inOutFSColor specifies the input color to the first stage and is updated
to be the |
| 290 * output color of the last stage. fsInOutColorKnownValue specifies whether
the input color | 287 * output color of the last stage. fsInOutColorKnownValue specifies whether
the input color |
| 291 * has a known constant value and is updated to refer to the status of the o
utput color. | 288 * has a known constant value and is updated to refer to the status of the o
utput color. |
| 292 * The handles to texture samplers for effectStage[i] are added to effectSam
plerHandles[i]. The | 289 * The handles to texture samplers for effectStage[i] are added to effectSam
plerHandles[i]. The |
| 293 * glEffects array is updated to contain the GrGLEffect generated for each e
ntry in | 290 * glEffects array is updated to contain the GrGLEffect generated for each e
ntry in |
| (...skipping 29 matching lines...) Expand all Loading... |
| 323 return fEffectAttributes; | 320 return fEffectAttributes; |
| 324 } | 321 } |
| 325 const SkString* getEffectAttributeName(int attributeIndex) const; | 322 const SkString* getEffectAttributeName(int attributeIndex) const; |
| 326 | 323 |
| 327 // TODO: Make this do all the compiling, linking, etc. | 324 // TODO: Make this do all the compiling, linking, etc. |
| 328 void finished(GrGLuint programID); | 325 void finished(GrGLuint programID); |
| 329 | 326 |
| 330 const GrGLContextInfo& ctxInfo() const { return fCtxInfo; } | 327 const GrGLContextInfo& ctxInfo() const { return fCtxInfo; } |
| 331 | 328 |
| 332 private: | 329 private: |
| 333 void codeAppendf(ShaderType type, const char format[], va_list args); | |
| 334 void codeAppend(ShaderType type, const char* str); | |
| 335 | |
| 336 typedef GrTAllocator<GrGLShaderVar> VarArray; | 330 typedef GrTAllocator<GrGLShaderVar> VarArray; |
| 337 | 331 |
| 338 void appendDecls(const VarArray&, SkString*) const; | 332 void appendDecls(const VarArray&, SkString*) const; |
| 339 void appendUniformDecls(ShaderType, SkString*) const; | 333 void appendUniformDecls(ShaderVisibility, SkString*) const; |
| 340 | 334 |
| 341 typedef GrGLUniformManager::BuilderUniform BuilderUniform; | 335 typedef GrGLUniformManager::BuilderUniform BuilderUniform; |
| 342 GrGLUniformManager::BuilderUniformArray fUniforms; | 336 GrGLUniformManager::BuilderUniformArray fUniforms; |
| 343 | 337 |
| 344 // TODO: Everything below here private. | 338 // TODO: Everything below here private. |
| 345 public: | 339 public: |
| 346 | 340 |
| 347 VarArray fVSAttrs; | 341 VarArray fVSAttrs; |
| 348 VarArray fVSOutputs; | 342 VarArray fVSOutputs; |
| 349 VarArray fGSInputs; | 343 VarArray fGSInputs; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 /** | 401 /** |
| 408 * Features that should only be enabled by GrGLShaderBuilder itself. | 402 * Features that should only be enabled by GrGLShaderBuilder itself. |
| 409 */ | 403 */ |
| 410 enum GLSLPrivateFeature { | 404 enum GLSLPrivateFeature { |
| 411 kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1, | 405 kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1, |
| 412 kEXTShaderFramebufferFetch_GLSLPrivateFeature, | 406 kEXTShaderFramebufferFetch_GLSLPrivateFeature, |
| 413 kNVShaderFramebufferFetch_GLSLPrivateFeature, | 407 kNVShaderFramebufferFetch_GLSLPrivateFeature, |
| 414 }; | 408 }; |
| 415 bool enablePrivateFeature(GLSLPrivateFeature); | 409 bool enablePrivateFeature(GLSLPrivateFeature); |
| 416 | 410 |
| 417 // If we ever have VS/GS features we can expand this to take a bitmask of Sh
aderType and track | 411 // If we ever have VS/GS features we can expand this to take a bitmask of Sh
aderVisibility and |
| 418 // the enables separately for each shader. | 412 // track the enables separately for each shader. |
| 419 void addFSFeature(uint32_t featureBit, const char* extensionName); | 413 void addFSFeature(uint32_t featureBit, const char* extensionName); |
| 420 | 414 |
| 421 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix | 415 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix |
| 422 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're | 416 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're |
| 423 // generating stage code. | 417 // generating stage code. |
| 424 void nameVariable(SkString* out, char prefix, const char* name); | 418 void nameVariable(SkString* out, char prefix, const char* name); |
| 425 | 419 |
| 426 // Interpretation of DstReadKey when generating code | 420 // Interpretation of DstReadKey when generating code |
| 427 enum { | 421 enum { |
| 428 kNoDstRead_DstReadKey = 0, | 422 kNoDstRead_DstReadKey = 0, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 459 bool fTopLeftFragPosRead; | 453 bool fTopLeftFragPosRead; |
| 460 | 454 |
| 461 SkSTArray<10, AttributePair, true> fEffectAttributes; | 455 SkSTArray<10, AttributePair, true> fEffectAttributes; |
| 462 | 456 |
| 463 GrGLShaderVar* fPositionVar; | 457 GrGLShaderVar* fPositionVar; |
| 464 GrGLShaderVar* fLocalCoordsVar; | 458 GrGLShaderVar* fLocalCoordsVar; |
| 465 | 459 |
| 466 }; | 460 }; |
| 467 | 461 |
| 468 #endif | 462 #endif |
| OLD | NEW |