| 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 23 matching lines...) Expand all Loading... |
| 34 typedef GrGLProgramEffects::TextureSampler TextureSampler; | 34 typedef GrGLProgramEffects::TextureSampler TextureSampler; |
| 35 typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray; | 35 typedef GrGLProgramEffects::TransformedCoordsArray TransformedCoordsArray; |
| 36 | 36 |
| 37 enum ShaderVisibility { | 37 enum ShaderVisibility { |
| 38 kVertex_Visibility = 0x1, | 38 kVertex_Visibility = 0x1, |
| 39 kGeometry_Visibility = 0x2, | 39 kGeometry_Visibility = 0x2, |
| 40 kFragment_Visibility = 0x4, | 40 kFragment_Visibility = 0x4, |
| 41 }; | 41 }; |
| 42 | 42 |
| 43 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 43 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
| 44 typedef GrGLProgramDataManager::VaryingHandle VaryingHandle; |
| 44 | 45 |
| 45 // Handles for program uniforms (other than per-effect uniforms) | 46 // Handles for program uniforms (other than per-effect uniforms) |
| 46 struct BuiltinUniformHandles { | 47 struct BuiltinUniformHandles { |
| 47 UniformHandle fViewMatrixUni; | 48 UniformHandle fViewMatrixUni; |
| 48 UniformHandle fRTAdjustmentUni; | 49 UniformHandle fRTAdjustmentUni; |
| 49 UniformHandle fColorUni; | 50 UniformHandle fColorUni; |
| 50 UniformHandle fCoverageUni; | 51 UniformHandle fCoverageUni; |
| 51 | 52 |
| 52 // We use the render target height to provide a y-down frag coord when s
pecifying | 53 // We use the render target height to provide a y-down frag coord when s
pecifying |
| 53 // origin_upper_left is not supported. | 54 // origin_upper_left is not supported. |
| 54 UniformHandle fRTHeightUni; | 55 UniformHandle fRTHeightUni; |
| 55 | 56 |
| 56 // Uniforms for computing texture coords to do the dst-copy lookup | 57 // Uniforms for computing texture coords to do the dst-copy lookup |
| 57 UniformHandle fDstCopyTopLeftUni; | 58 UniformHandle fDstCopyTopLeftUni; |
| 58 UniformHandle fDstCopyScaleUni; | 59 UniformHandle fDstCopyScaleUni; |
| 59 UniformHandle fDstCopySamplerUni; | 60 UniformHandle fDstCopySamplerUni; |
| 60 }; | 61 }; |
| 61 | 62 |
| 62 struct UniformInfo { | 63 struct UniformInfo { |
| 63 GrGLShaderVar fVariable; | 64 GrGLShaderVar fVariable; |
| 64 uint32_t fVisibility; | 65 uint32_t fVisibility; |
| 65 GrGLint fLocation; | 66 GrGLint fLocation; |
| 66 }; | 67 }; |
| 67 | 68 |
| 68 // This uses an allocator rather than array so that the GrGLShaderVars don't
move in memory | 69 // This uses an allocator rather than array so that the GrGLShaderVars don't
move in memory |
| 69 // after they are inserted. Users of GrGLShaderBuilder get refs to the vars
and ptrs to their | 70 // after they are inserted. Users of GrGLShaderBuilder get refs to the vars
and ptrs to their |
| 70 // name strings. Otherwise, we'd have to hand out copies. | 71 // name strings. Otherwise, we'd have to hand out copies. |
| 71 typedef GrTAllocator<UniformInfo> UniformInfoArray; | 72 typedef GrTAllocator<UniformInfo> UniformInfoArray; |
| 72 | 73 |
| 74 struct SeparableVaryingInfo { |
| 75 GrGLShaderVar fVariable; |
| 76 GrGLint fLocation; |
| 77 }; |
| 78 |
| 79 typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray; |
| 80 |
| 73 /** Generates a shader program. | 81 /** Generates a shader program. |
| 74 * | 82 * |
| 75 * The program implements what is specified in the stages given as input. | 83 * The program implements what is specified in the stages given as input. |
| 76 * After successful generation, the builder result objects are available | 84 * After successful generation, the builder result objects are available |
| 77 * to be used. | 85 * to be used. |
| 78 * @return true if generation was successful. | 86 * @return true if generation was successful. |
| 79 */ | 87 */ |
| 80 bool genProgram(const GrEffectStage* inColorStages[], | 88 bool genProgram(const GrEffectStage* inColorStages[], |
| 81 const GrEffectStage* inCoverageStages[]); | 89 const GrEffectStage* inCoverageStages[]); |
| 82 | 90 |
| 83 // Below are the results of the shader generation. | 91 // Below are the results of the shader generation. |
| 84 | 92 |
| 85 GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return f
ColorEffects.get(); } | 93 GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return f
ColorEffects.get(); } |
| 86 GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); retur
n fCoverageEffects.get(); } | 94 GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); retur
n fCoverageEffects.get(); } |
| 87 const BuiltinUniformHandles& getBuiltinUniformHandles() const { | 95 const BuiltinUniformHandles& getBuiltinUniformHandles() const { |
| 88 SkASSERT(fProgramID); | 96 SkASSERT(fProgramID); |
| 89 return fUniformHandles; | 97 return fUniformHandles; |
| 90 } | 98 } |
| 91 GrGLuint getProgramID() const { SkASSERT(fProgramID); return fProgramID; } | 99 GrGLuint getProgramID() const { SkASSERT(fProgramID); return fProgramID; } |
| 92 bool hasVertexShader() const { SkASSERT(fProgramID); return fHasVertexShader
; } | 100 bool hasVertexShader() const { SkASSERT(fProgramID); return fHasVertexShader
; } |
| 93 int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetC
nt; } | 101 int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetC
nt; } |
| 94 const UniformInfoArray& getUniformInfos() const { return fUniforms; } | 102 const UniformInfoArray& getUniformInfos() const { return fUniforms; } |
| 103 const SeparableVaryingInfoArray& getSeparableVaryingInfos() const { |
| 104 return fSeparableVaryingInfos; |
| 105 } |
| 95 | 106 |
| 96 virtual ~GrGLShaderBuilder() {} | 107 virtual ~GrGLShaderBuilder() {} |
| 97 | 108 |
| 98 /** | 109 /** |
| 99 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile | 110 * Use of these features may require a GLSL extension to be enabled. Shaders
may not compile |
| 100 * if code is added that uses one of these features without calling enableFe
ature() | 111 * if code is added that uses one of these features without calling enableFe
ature() |
| 101 */ | 112 */ |
| 102 enum GLSLFeature { | 113 enum GLSLFeature { |
| 103 kStandardDerivatives_GLSLFeature = 0, | 114 kStandardDerivatives_GLSLFeature = 0, |
| 104 | 115 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 /** Returns a variable name that represents the position of the fragment in
the FS. The position | 221 /** Returns a variable name that represents the position of the fragment in
the FS. The position |
| 211 is in device space (e.g. 0,0 is the top left and pixel centers are at ha
lf-integers). */ | 222 is in device space (e.g. 0,0 is the top left and pixel centers are at ha
lf-integers). */ |
| 212 const char* fragmentPosition(); | 223 const char* fragmentPosition(); |
| 213 | 224 |
| 214 /** Returns the variable name that holds the color of the destination pixel.
This may be NULL if | 225 /** Returns the variable name that holds the color of the destination pixel.
This may be NULL if |
| 215 no effect advertised that it will read the destination. */ | 226 no effect advertised that it will read the destination. */ |
| 216 const char* dstColor(); | 227 const char* dstColor(); |
| 217 | 228 |
| 218 const GrGLContextInfo& ctxInfo() const; | 229 const GrGLContextInfo& ctxInfo() const; |
| 219 | 230 |
| 231 GrGpuGL* gpu() const { return fGpu; } |
| 232 |
| 220 /** | 233 /** |
| 221 * Helper for begining and ending a block in the fragment code. TODO: Make G
rGLShaderBuilder | 234 * Helper for begining and ending a block in the fragment code. TODO: Make G
rGLShaderBuilder |
| 222 * aware of all blocks and turn single \t's into the correct number of tabs
(or spaces) so that | 235 * aware of all blocks and turn single \t's into the correct number of tabs
(or spaces) so that |
| 223 * our shaders print pretty without effect writers tracking indentation. | 236 * our shaders print pretty without effect writers tracking indentation. |
| 224 */ | 237 */ |
| 225 class FSBlock { | 238 class FSBlock { |
| 226 public: | 239 public: |
| 227 FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) { | 240 FSBlock(GrGLShaderBuilder* builder) : fBuilder(builder) { |
| 228 SkASSERT(NULL != builder); | 241 SkASSERT(NULL != builder); |
| 229 fBuilder->fsCodeAppend("\t{\n"); | 242 fBuilder->fsCodeAppend("\t{\n"); |
| 230 } | 243 } |
| 231 | 244 |
| 232 ~FSBlock() { | 245 ~FSBlock() { |
| 233 fBuilder->fsCodeAppend("\t}\n"); | 246 fBuilder->fsCodeAppend("\t}\n"); |
| 234 } | 247 } |
| 235 private: | 248 private: |
| 236 GrGLShaderBuilder* fBuilder; | 249 GrGLShaderBuilder* fBuilder; |
| 237 }; | 250 }; |
| 238 | 251 |
| 239 protected: | 252 protected: |
| 240 GrGLShaderBuilder(GrGpuGL*, const GrGLProgramDesc&); | 253 GrGLShaderBuilder(GrGpuGL*, const GrGLProgramDesc&); |
| 241 | 254 |
| 242 GrGpuGL* gpu() const { return fGpu; } | |
| 243 | |
| 244 const GrGLProgramDesc& desc() const { return fDesc; } | 255 const GrGLProgramDesc& desc() const { return fDesc; } |
| 245 | 256 |
| 246 /** Add input/output variable declarations (i.e. 'varying') to the fragment
shader. */ | |
| 247 GrGLShaderVar& fsInputAppend() { return fFSInputs.push_back(); } | |
| 248 | |
| 249 // Helper for emitEffects(). | 257 // Helper for emitEffects(). |
| 250 void createAndEmitEffects(GrGLProgramEffectsBuilder*, | 258 void createAndEmitEffects(GrGLProgramEffectsBuilder*, |
| 251 const GrEffectStage* effectStages[], | 259 const GrEffectStage* effectStages[], |
| 252 int effectCnt, | 260 int effectCnt, |
| 253 const GrGLProgramDesc::EffectKeyProvider&, | 261 const GrGLProgramDesc::EffectKeyProvider&, |
| 254 GrGLSLExpr4* inOutFSColor); | 262 GrGLSLExpr4* inOutFSColor); |
| 255 | 263 |
| 256 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix | 264 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix |
| 257 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're | 265 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're |
| 258 // generating stage code. | 266 // generating stage code. |
| 259 void nameVariable(SkString* out, char prefix, const char* name); | 267 void nameVariable(SkString* out, char prefix, const char* name); |
| 260 | 268 |
| 261 virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>
* shaderIds) const; | 269 virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>
* shaderIds) const; |
| 262 | 270 |
| 263 virtual void bindProgramLocations(GrGLuint programId); | 271 virtual void bindProgramLocations(GrGLuint programId); |
| 264 void resolveProgramLocations(GrGLuint programId); | 272 void resolveProgramLocations(GrGLuint programId); |
| 265 | 273 |
| 266 void appendDecls(const VarArray&, SkString*) const; | 274 void appendDecls(const VarArray&, SkString*) const; |
| 267 void appendUniformDecls(ShaderVisibility, SkString*) const; | 275 void appendUniformDecls(ShaderVisibility, SkString*) const; |
| 268 | 276 |
| 269 SkAutoTUnref<GrGLProgramEffects> fColorEffects; | 277 SkAutoTUnref<GrGLProgramEffects> fColorEffects; |
| 270 SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; | 278 SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; |
| 271 BuiltinUniformHandles fUniformHandles; | 279 BuiltinUniformHandles fUniformHandles; |
| 272 bool fHasVertexShader; | 280 bool fHasVertexShader; |
| 273 int fTexCoordSetCnt; | 281 int fTexCoordSetCnt; |
| 274 GrGLuint fProgramID; | 282 GrGLuint fProgramID; |
| 283 |
| 284 VarArray fFSInputs; |
| 285 SeparableVaryingInfoArray fSeparableVaryingInfos; |
| 286 |
| 275 private: | 287 private: |
| 276 class CodeStage : SkNoncopyable { | 288 class CodeStage : SkNoncopyable { |
| 277 public: | 289 public: |
| 278 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} | 290 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} |
| 279 | 291 |
| 280 bool inStageCode() const { | 292 bool inStageCode() const { |
| 281 this->validate(); | 293 this->validate(); |
| 282 return NULL != fEffectStage; | 294 return NULL != fEffectStage; |
| 283 } | 295 } |
| 284 | 296 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. | 400 kNoFragPosRead_FragPosKey = 0, // The fragment positition wil
l not be needed. |
| 389 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. | 401 kTopLeftFragPosRead_FragPosKey = 0x1,// Read frag pos relative to t
op-left. |
| 390 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. | 402 kBottomLeftFragPosRead_FragPosKey = 0x2,// Read frag pos relative to b
ottom-left. |
| 391 }; | 403 }; |
| 392 | 404 |
| 393 const GrGLProgramDesc& fDesc; | 405 const GrGLProgramDesc& fDesc; |
| 394 GrGpuGL* fGpu; | 406 GrGpuGL* fGpu; |
| 395 uint32_t fFSFeaturesAddedMask; | 407 uint32_t fFSFeaturesAddedMask; |
| 396 SkString fFSFunctions; | 408 SkString fFSFunctions; |
| 397 SkString fFSExtensions; | 409 SkString fFSExtensions; |
| 398 VarArray fFSInputs; | |
| 399 VarArray fFSOutputs; | 410 VarArray fFSOutputs; |
| 400 UniformInfoArray fUniforms; | 411 UniformInfoArray fUniforms; |
| 401 | 412 |
| 402 SkString fFSCode; | 413 SkString fFSCode; |
| 403 | 414 |
| 404 bool fSetupFragPosition; | 415 bool fSetupFragPosition; |
| 405 bool fTopLeftFragPosRead; | 416 bool fTopLeftFragPosRead; |
| 406 | 417 |
| 407 bool fHasCustomColorOutput; | 418 bool fHasCustomColorOutput; |
| 408 bool fHasSecondaryOutput; | 419 bool fHasSecondaryOutput; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 431 bool addAttribute(GrSLType type, const char* name); | 442 bool addAttribute(GrSLType type, const char* name); |
| 432 | 443 |
| 433 /** Add a varying variable to the current program to pass values between vert
ex and fragment | 444 /** Add a varying variable to the current program to pass values between vert
ex and fragment |
| 434 shaders. If the last two parameters are non-NULL, they are filled in wit
h the name | 445 shaders. If the last two parameters are non-NULL, they are filled in wit
h the name |
| 435 generated. */ | 446 generated. */ |
| 436 void addVarying(GrSLType type, | 447 void addVarying(GrSLType type, |
| 437 const char* name, | 448 const char* name, |
| 438 const char** vsOutName = NULL, | 449 const char** vsOutName = NULL, |
| 439 const char** fsInName = NULL); | 450 const char** fsInName = NULL); |
| 440 | 451 |
| 452 /** Add a separable varying input variable to the current program. |
| 453 * A separable varying (fragment shader input) is a varying that can be used
also when vertex |
| 454 * shaders are not used. With a vertex shader, the operation is same as with
other |
| 455 * varyings. Without a vertex shader, such as with NV_path_rendering, GL API
s are used to |
| 456 * populate the variable. The APIs can refer to the variable through the ret
urned handle. |
| 457 */ |
| 458 VaryingHandle addSeparableVarying(GrSLType type, |
| 459 const char* name, |
| 460 const char** vsOutName, |
| 461 const char** fsInName); |
| 462 |
| 441 /** Returns a vertex attribute that represents the vertex position in the VS
. This is the | 463 /** Returns a vertex attribute that represents the vertex position in the VS
. This is the |
| 442 pre-matrix position and is commonly used by effects to compute texture c
oords via a matrix. | 464 pre-matrix position and is commonly used by effects to compute texture c
oords via a matrix. |
| 443 */ | 465 */ |
| 444 const GrGLShaderVar& positionAttribute() const { return *fPositionVar; } | 466 const GrGLShaderVar& positionAttribute() const { return *fPositionVar; } |
| 445 | 467 |
| 446 /** Returns a vertex attribute that represents the local coords in the VS. T
his may be the same | 468 /** Returns a vertex attribute that represents the local coords in the VS. T
his may be the same |
| 447 as positionAttribute() or it may not be. It depends upon whether the ren
dering code | 469 as positionAttribute() or it may not be. It depends upon whether the ren
dering code |
| 448 specified explicit local coords or not in the GrDrawState. */ | 470 specified explicit local coords or not in the GrDrawState. */ |
| 449 const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar;
} | 471 const GrGLShaderVar& localCoordsAttribute() const { return *fLocalCoordsVar;
} |
| 450 | 472 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 int effectCnt, | 530 int effectCnt, |
| 509 const GrGLProgramDesc::Effe
ctKeyProvider&, | 531 const GrGLProgramDesc::Effe
ctKeyProvider&, |
| 510 GrGLSLExpr4* inOutFSColor)
SK_OVERRIDE; | 532 GrGLSLExpr4* inOutFSColor)
SK_OVERRIDE; |
| 511 | 533 |
| 512 virtual void emitCodeAfterEffects() SK_OVERRIDE {} | 534 virtual void emitCodeAfterEffects() SK_OVERRIDE {} |
| 513 | 535 |
| 514 typedef GrGLShaderBuilder INHERITED; | 536 typedef GrGLShaderBuilder INHERITED; |
| 515 }; | 537 }; |
| 516 | 538 |
| 517 #endif | 539 #endif |
| OLD | NEW |