| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 GrGLProgramBuilder_DEFINED | 8 #ifndef GrGLProgramBuilder_DEFINED |
| 9 #define GrGLProgramBuilder_DEFINED | 9 #define GrGLProgramBuilder_DEFINED |
| 10 | 10 |
| 11 #include "GrAllocator.h" | |
| 12 #include "GrBackendProcessorFactory.h" | |
| 13 #include "GrColor.h" | |
| 14 #include "GrProcessor.h" | |
| 15 #include "GrGLFragmentShaderBuilder.h" | 11 #include "GrGLFragmentShaderBuilder.h" |
| 16 #include "GrGLGeometryShaderBuilder.h" | 12 #include "GrGLGeometryShaderBuilder.h" |
| 17 #include "GrGLVertexShaderBuilder.h" | 13 #include "GrGLVertexShaderBuilder.h" |
| 18 #include "SkTypes.h" | 14 #include "../GrGLProgramDataManager.h" |
| 19 #include "gl/GrGLProcessor.h" | 15 #include "../GrGLUniformHandle.h" |
| 20 #include "gl/GrGLProgramDesc.h" | |
| 21 #include "gl/GrGLProgramEffects.h" | |
| 22 #include "gl/GrGLSL.h" | |
| 23 #include "gl/GrGLProgramDataManager.h" | |
| 24 | 16 |
| 25 #include <stdarg.h> | 17 class GrGLInstalledProcessors; |
| 26 | 18 |
| 27 class GrGLContextInfo; | 19 /* |
| 28 class GrProcessorStage; | 20 * This is the base class for a series of interfaces. This base class *MUST* re
main abstract with |
| 29 class GrGLProgramDesc; | 21 * NO data members because it is used in multiple interface inheritance |
| 30 | 22 */ |
| 31 /** | 23 class GrGLUniformBuilder { |
| 32 Contains all the incremental state of a shader as it is being built,as well as
helpers to | |
| 33 manipulate that state. | |
| 34 */ | |
| 35 class GrGLProgramBuilder { | |
| 36 public: | 24 public: |
| 37 enum ShaderVisibility { | 25 enum ShaderVisibility { |
| 38 kVertex_Visibility = 0x1, | 26 kVertex_Visibility = 0x1, |
| 39 kGeometry_Visibility = 0x2, | 27 kGeometry_Visibility = 0x2, |
| 40 kFragment_Visibility = 0x4, | 28 kFragment_Visibility = 0x4, |
| 41 }; | 29 }; |
| 42 | 30 |
| 31 virtual ~GrGLUniformBuilder() {} |
| 32 |
| 43 typedef GrGLProgramDataManager::UniformHandle UniformHandle; | 33 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
| 44 typedef GrGLProgramDataManager::VaryingHandle VaryingHandle; | |
| 45 | 34 |
| 46 // Handles for program uniforms (other than per-effect uniforms) | 35 /** Add a uniform variable to the current program, that has visibility in on
e or more shaders. |
| 47 struct BuiltinUniformHandles { | 36 visibility is a bitfield of ShaderVisibility values indicating from whic
h shaders the |
| 48 UniformHandle fViewMatrixUni; | 37 uniform should be accessible. At least one bit must be set. Geometry sha
der uniforms are not |
| 49 UniformHandle fRTAdjustmentUni; | 38 supported at this time. The actual uniform name will be mangled. If outN
ame is not NULL then |
| 50 UniformHandle fColorUni; | 39 it will refer to the final uniform name after return. Use the addUniform
Array variant to add |
| 51 UniformHandle fCoverageUni; | 40 an array of uniforms. */ |
| 41 virtual UniformHandle addUniform(uint32_t visibility, |
| 42 GrSLType type, |
| 43 const char* name, |
| 44 const char** outName = NULL) = 0; |
| 45 virtual UniformHandle addUniformArray(uint32_t visibility, |
| 46 GrSLType type, |
| 47 const char* name, |
| 48 int arrayCount, |
| 49 const char** outName = NULL) = 0; |
| 52 | 50 |
| 53 // We use the render target height to provide a y-down frag coord when s
pecifying | 51 virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const = 0; |
| 54 // origin_upper_left is not supported. | |
| 55 UniformHandle fRTHeightUni; | |
| 56 | 52 |
| 57 // Uniforms for computing texture coords to do the dst-copy lookup | 53 /** |
| 58 UniformHandle fDstCopyTopLeftUni; | 54 * Shortcut for getUniformVariable(u).c_str() |
| 59 UniformHandle fDstCopyScaleUni; | 55 */ |
| 60 UniformHandle fDstCopySamplerUni; | 56 virtual const char* getUniformCStr(UniformHandle u) const = 0; |
| 61 }; | |
| 62 | 57 |
| 63 struct UniformInfo { | 58 virtual const GrGLContextInfo& ctxInfo() const = 0; |
| 64 GrGLShaderVar fVariable; | |
| 65 uint32_t fVisibility; | |
| 66 GrGLint fLocation; | |
| 67 }; | |
| 68 | 59 |
| 69 // This uses an allocator rather than array so that the GrGLShaderVars don't
move in memory | 60 virtual GrGpuGL* gpu() const = 0; |
| 70 // after they are inserted. Users of GrGLShaderBuilder get refs to the vars
and ptrs to their | |
| 71 // name strings. Otherwise, we'd have to hand out copies. | |
| 72 typedef GrTAllocator<UniformInfo> UniformInfoArray; | |
| 73 | 61 |
| 74 struct SeparableVaryingInfo { | 62 /* |
| 75 GrGLShaderVar fVariable; | 63 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE |
| 76 GrGLint fLocation; | 64 */ |
| 77 }; | 65 }; |
| 78 | 66 |
| 79 typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray; | 67 class GrGLGeometryProcessorProgramBuilder : public virtual GrGLUniformBuilder { |
| 68 public: |
| 69 virtual void addVarying(GrSLType type, |
| 70 const char* name, |
| 71 const char** vsOutName = NULL, |
| 72 const char** fsInName = NULL, |
| 73 GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::
kDefault_Precision) = 0; |
| 80 | 74 |
| 75 virtual GrGLProcessorFragmentShaderBuilder* getFragmentShaderBuilder() = 0; |
| 76 virtual GrGLVertexShaderBuilder* getVertexShaderBuilder() = 0; |
| 77 |
| 78 /* |
| 79 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE |
| 80 */ |
| 81 }; |
| 82 |
| 83 class GrGLFragmentProcessorProgramBuilder : public virtual GrGLUniformBuilder { |
| 84 public: |
| 85 virtual GrGLFragmentProcessorFragmentShaderBuilder* getFragmentShaderBuilder
() = 0; |
| 86 |
| 87 /* |
| 88 * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE |
| 89 */ |
| 90 }; |
| 91 |
| 92 /* |
| 93 * Please note - no diamond problems because of virtual inheritance. Also, this
both base classes |
| 94 * are pure virtual with no data members. This is the base class for program bu
ilding. It |
| 95 * implements the interfaces above for specific processor types. Subclasses are
nearly identical |
| 96 * but each has their own way of emitting transforms. State for each of the ele
ments of the shader |
| 97 * pipeline, ie vertex, fragment, geometry, etc, lives in those respective build
ers |
| 98 */ |
| 99 class GrGLProgramBuilder : public GrGLGeometryProcessorProgramBuilder, |
| 100 public GrGLFragmentProcessorProgramBuilder { |
| 101 public: |
| 81 /** Generates a shader program. | 102 /** Generates a shader program. |
| 82 * | 103 * |
| 83 * The program implements what is specified in the stages given as input. | 104 * The program implements what is specified in the stages given as input. |
| 84 * After successful generation, the builder result objects are available | 105 * After successful generation, the builder result objects are available |
| 85 * to be used. | 106 * to be used. |
| 86 * @return true if generation was successful. | 107 * @return true if generation was successful. |
| 87 */ | 108 */ |
| 88 | 109 static GrGLProgram* CreateProgram(const GrGLProgramDesc&, |
| 89 bool genProgram(const GrGeometryStage* inGeometryProcessor, | 110 GrGpu::DrawType, |
| 90 const GrFragmentStage* inColorStages[], | 111 const GrGeometryStage* inGeometryProcessor
, |
| 91 const GrFragmentStage* inCoverageStages[]); | 112 const GrFragmentStage* inColorStages[], |
| 92 | 113 const GrFragmentStage* inCoverageStages[], |
| 93 GrGLProgramEffects* getGeometryProcessor() const { | 114 GrGpuGL* gpu); |
| 94 SkASSERT(fProgramID); return fGeometryProcessor.get(); | 115 |
| 95 } | 116 virtual UniformHandle addUniform(uint32_t visibility, |
| 96 GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return f
ColorEffects.get(); } | 117 GrSLType type, |
| 97 GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); retur
n fCoverageEffects.get(); } | 118 const char* name, |
| 98 const BuiltinUniformHandles& getBuiltinUniformHandles() const { | 119 const char** outName = NULL) SK_OVERRIDE { |
| 99 SkASSERT(fProgramID); | |
| 100 return fUniformHandles; | |
| 101 } | |
| 102 GrGLuint getProgramID() const { SkASSERT(fProgramID); return fProgramID; } | |
| 103 bool hasVertexShader() const { SkASSERT(fProgramID); return !fFragOnly; } | |
| 104 int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetC
nt; } | |
| 105 const UniformInfoArray& getUniformInfos() const { return fUniforms; } | |
| 106 const SeparableVaryingInfoArray& getSeparableVaryingInfos() const { | |
| 107 return fSeparableVaryingInfos; | |
| 108 } | |
| 109 | |
| 110 virtual ~GrGLProgramBuilder() {} | |
| 111 | |
| 112 /** Add a uniform variable to the current program, that has visibility in on
e or more shaders. | |
| 113 visibility is a bitfield of ShaderVisibility values indicating from whic
h shaders the | |
| 114 uniform should be accessible. At least one bit must be set. Geometry sha
der uniforms are not | |
| 115 supported at this time. The actual uniform name will be mangled. If outN
ame is not NULL then | |
| 116 it will refer to the final uniform name after return. Use the addUniform
Array variant to add | |
| 117 an array of uniforms. */ | |
| 118 GrGLProgramDataManager::UniformHandle addUniform(uint32_t visibility, | |
| 119 GrSLType type, | |
| 120 const char* name, | |
| 121 const char** outName = NULL
) { | |
| 122 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); | 120 return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNon
Array, outName); |
| 123 } | 121 } |
| 124 GrGLProgramDataManager::UniformHandle addUniformArray(uint32_t visibility, | 122 virtual UniformHandle addUniformArray(uint32_t visibility, |
| 125 GrSLType type, | 123 GrSLType type, |
| 126 const char* name, | 124 const char* name, |
| 127 int arrayCount, | 125 int arrayCount, |
| 128 const char** outName =
NULL); | 126 const char** outName = NULL) SK_OVERRI
DE; |
| 129 | 127 |
| 130 const GrGLShaderVar& getUniformVariable(GrGLProgramDataManager::UniformHandl
e u) const { | 128 virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const SK_OV
ERRIDE { |
| 131 return fUniforms[u.toShaderBuilderIndex()].fVariable; | 129 return fUniforms[u.toShaderBuilderIndex()].fVariable; |
| 132 } | 130 } |
| 133 | 131 |
| 134 /** | 132 virtual const char* getUniformCStr(UniformHandle u) const SK_OVERRIDE { |
| 135 * Shortcut for getUniformVariable(u).c_str() | |
| 136 */ | |
| 137 const char* getUniformCStr(GrGLProgramDataManager::UniformHandle u) const { | |
| 138 return this->getUniformVariable(u).c_str(); | 133 return this->getUniformVariable(u).c_str(); |
| 139 } | 134 } |
| 140 | 135 |
| 141 const GrGLContextInfo& ctxInfo() const; | 136 virtual const GrGLContextInfo& ctxInfo() const SK_OVERRIDE; |
| 142 | 137 |
| 143 GrGLFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; } | 138 virtual GrGpuGL* gpu() const SK_OVERRIDE { return fGpu; } |
| 144 GrGpuGL* gpu() const { return fGpu; } | 139 |
| 140 virtual GrGLFragmentShaderBuilder* getFragmentShaderBuilder() SK_OVERRIDE {
return &fFS; } |
| 141 virtual GrGLVertexShaderBuilder* getVertexShaderBuilder() SK_OVERRIDE { retu
rn &fVS; } |
| 142 |
| 143 virtual void addVarying(GrSLType type, |
| 144 const char* name, |
| 145 const char** vsOutName = NULL, |
| 146 const char** fsInName = NULL, |
| 147 GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::
kDefault_Precision); |
| 148 |
| 149 // Handles for program uniforms (other than per-effect uniforms) |
| 150 struct BuiltinUniformHandles { |
| 151 UniformHandle fViewMatrixUni; |
| 152 UniformHandle fRTAdjustmentUni; |
| 153 UniformHandle fColorUni; |
| 154 UniformHandle fCoverageUni; |
| 155 |
| 156 // We use the render target height to provide a y-down frag coord when s
pecifying |
| 157 // origin_upper_left is not supported. |
| 158 UniformHandle fRTHeightUni; |
| 159 |
| 160 // Uniforms for computing texture coords to do the dst-copy lookup |
| 161 UniformHandle fDstCopyTopLeftUni; |
| 162 UniformHandle fDstCopyScaleUni; |
| 163 UniformHandle fDstCopySamplerUni; |
| 164 }; |
| 145 | 165 |
| 146 protected: | 166 protected: |
| 147 typedef GrTAllocator<GrGLShaderVar> VarArray; | 167 static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&, |
| 168 GrGpu::DrawType, |
| 169 bool hasGeometryProcessor, |
| 170 GrGpuGL*); |
| 171 |
| 148 GrGLProgramBuilder(GrGpuGL*, const GrGLProgramDesc&); | 172 GrGLProgramBuilder(GrGpuGL*, const GrGLProgramDesc&); |
| 149 | 173 |
| 150 const GrGLProgramDesc& desc() const { return fDesc; } | 174 const GrGLProgramDesc& desc() const { return fDesc; } |
| 151 | 175 const GrGLProgramDesc::KeyHeader& header() const { return fDesc.getHeader();
} |
| 152 // Helper for emitEffects(). | |
| 153 void createAndEmitEffects(const GrFragmentStage* effectStages[], | |
| 154 int effectCnt, | |
| 155 const GrGLProgramDesc::EffectKeyProvider&, | |
| 156 GrGLSLExpr4* inOutFSColor); | |
| 157 | |
| 158 /* | |
| 159 * A helper function called to emit the geometry processor as well as indivi
dual coverage | |
| 160 * and color stages. this will call into subclasses emit effect | |
| 161 */ | |
| 162 void emitEffect(const GrProcessorStage& effectStage, | |
| 163 int effectIndex, | |
| 164 const GrGLProgramDesc::EffectKeyProvider& keyProvider, | |
| 165 GrGLSLExpr4* inColor, | |
| 166 GrGLSLExpr4* outColor); | |
| 167 | |
| 168 /** | |
| 169 * Helper for emitEffect() in subclasses. Emits uniforms for an effect's tex
ture accesses and | |
| 170 * appends the necessary data to the TextureSamplerArray* object so effects
can add texture | |
| 171 * lookups to their code. This method is only meant to be called during the
construction phase. | |
| 172 */ | |
| 173 void emitSamplers(const GrProcessor& effect, | |
| 174 GrGLProcessor::TextureSamplerArray* outSamplers); | |
| 175 | 176 |
| 176 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix | 177 // Generates a name for a variable. The generated string will be name prefix
ed by the prefix |
| 177 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're | 178 // char (unless the prefix is '\0'). It also mangles the name to be stage-sp
ecific if we're |
| 178 // generating stage code. | 179 // generating stage code. |
| 179 void nameVariable(SkString* out, char prefix, const char* name); | 180 void nameVariable(SkString* out, char prefix, const char* name); |
| 180 | 181 |
| 181 virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>
* shaderIds) const; | 182 void setupUniformColorIfNeeded(const GrGLProgramDesc::ColorInput& colorInput
, |
| 182 | 183 const char* name, |
| 183 virtual void bindProgramLocations(GrGLuint programId); | 184 GrGLSLExpr4* input); |
| 184 void resolveProgramLocations(GrGLuint programId); | 185 void transformGLToSkiaCoords(); |
| 185 | 186 void createAndEmitProcessors(const GrGeometryStage* geometryProcessor, |
| 186 void appendDecls(const VarArray&, SkString*) const; | 187 const GrFragmentStage* colorStages[], |
| 188 const GrFragmentStage* coverageStages[], |
| 189 GrGLSLExpr4* inputColor, |
| 190 GrGLSLExpr4* inputCoverage); |
| 191 template <class ProcessorStage> |
| 192 void createAndEmitProcessors(const ProcessorStage*[], |
| 193 int effectCnt, |
| 194 const GrGLProgramDesc::EffectKeyProvider&, |
| 195 GrGLSLExpr4* fsInOutColor, |
| 196 GrGLInstalledProcessors*); |
| 197 void verify(const GrGeometryProcessor&); |
| 198 void verify(const GrFragmentProcessor&); |
| 199 void emitSamplers(const GrProcessor&, |
| 200 GrGLProcessor::TextureSamplerArray* outSamplers, |
| 201 GrGLInstalledProcessors*); |
| 202 |
| 203 // each specific program builder has a distinct transform and must override
this function |
| 204 virtual void emitTransforms(const GrProcessorStage&, |
| 205 GrGLProcessor::TransformedCoordsArray* outCoords, |
| 206 GrGLInstalledProcessors*) = 0; |
| 207 void transformSkiaToGLCoords(); |
| 208 void enableSecondaryOutput(const GrGLSLExpr4& inputColor, const GrGLSLExpr4&
inputCoverage); |
| 209 void combineColorAndCoverage(const GrGLSLExpr4& inputColor, const GrGLSLExpr
4& inputCoverage); |
| 210 GrGLProgram* compileBindLinkCreate(); |
| 211 void bindUniformLocations(GrGLuint programID); |
| 212 bool checkLinkStatus(GrGLuint programID); |
| 213 void resolveUniformLocations(GrGLuint programID); |
| 214 |
| 215 // the below function is a hook for nvpr es so that program creator can corr
ectly resolve |
| 216 // separable varyings after compilation |
| 217 virtual void resolveSeparableVaryings(GrGLuint programId) {} |
| 218 |
| 219 void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs
); |
| 220 void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs); |
| 221 |
| 222 // Subclasses create different programs |
| 223 virtual GrGLProgram* createProgram(GrGLuint programID) = 0; |
| 224 |
| 187 void appendUniformDecls(ShaderVisibility, SkString*) const; | 225 void appendUniformDecls(ShaderVisibility, SkString*) const; |
| 188 | 226 |
| 189 class CodeStage : SkNoncopyable { | 227 // reset is called by program creator between each processor's emit code. I
t increments the |
| 228 // stage offset for variable name mangling, and also ensures verfication var
iables in the |
| 229 // fragment shader are cleared. |
| 230 void reset() { |
| 231 this->enterStage(); |
| 232 this->addStage(); |
| 233 fFS.reset(); |
| 234 } |
| 235 void addStage() { fStageIndex++; } |
| 236 |
| 237 // This simple class exits the stage and then restores the stage when it goe
s out of scope |
| 238 class AutoStageRestore { |
| 190 public: | 239 public: |
| 191 CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} | 240 AutoStageRestore(GrGLProgramBuilder* pb) |
| 192 | 241 : fPB(pb), fOutOfStage(pb->fOutOfStage) { pb->exitStage(); } |
| 193 bool inStageCode() const { | 242 ~AutoStageRestore() { fPB->fOutOfStage = fOutOfStage; } |
| 194 this->validate(); | |
| 195 return SkToBool(fEffectStage); | |
| 196 } | |
| 197 | |
| 198 const GrProcessorStage* effectStage() const { | |
| 199 this->validate(); | |
| 200 return fEffectStage; | |
| 201 } | |
| 202 | |
| 203 int stageIndex() const { | |
| 204 this->validate(); | |
| 205 return fCurrentIndex; | |
| 206 } | |
| 207 | |
| 208 class AutoStageRestore : SkNoncopyable { | |
| 209 public: | |
| 210 AutoStageRestore(CodeStage* codeStage, const GrProcessorStage* newSt
age) { | |
| 211 SkASSERT(codeStage); | |
| 212 fSavedIndex = codeStage->fCurrentIndex; | |
| 213 fSavedEffectStage = codeStage->fEffectStage; | |
| 214 | |
| 215 if (NULL == newStage) { | |
| 216 codeStage->fCurrentIndex = -1; | |
| 217 } else { | |
| 218 codeStage->fCurrentIndex = codeStage->fNextIndex++; | |
| 219 } | |
| 220 codeStage->fEffectStage = newStage; | |
| 221 | |
| 222 fCodeStage = codeStage; | |
| 223 } | |
| 224 ~AutoStageRestore() { | |
| 225 fCodeStage->fCurrentIndex = fSavedIndex; | |
| 226 fCodeStage->fEffectStage = fSavedEffectStage; | |
| 227 } | |
| 228 private: | |
| 229 CodeStage* fCodeStage; | |
| 230 int fSavedIndex; | |
| 231 const GrProcessorStage* fSavedEffectStage; | |
| 232 }; | |
| 233 private: | 243 private: |
| 234 void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurre
ntIndex)); } | 244 GrGLProgramBuilder* fPB; |
| 235 int fNextIndex; | 245 bool fOutOfStage; |
| 236 int fCurrentIndex; | 246 }; |
| 237 const GrProcessorStage* fEffectStage; | 247 void exitStage() { fOutOfStage = true; } |
| 238 }; | 248 void enterStage() { fOutOfStage = false; } |
| 239 | 249 int stageIndex() const { return fStageIndex; } |
| 240 class GrGLProcessorEmitterInterface { | 250 |
| 241 public: | 251 typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider; |
| 242 virtual ~GrGLProcessorEmitterInterface() {} | 252 typedef GrGLProgramDataManager::UniformInfo UniformInfo; |
| 243 virtual GrGLProcessor* createGLInstance() = 0; | 253 typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; |
| 244 virtual void emit(const GrProcessorKey& key, | 254 |
| 245 const char* outColor, | 255 // number of each input/output type in a single allocation block, used by ma
ny builders |
| 246 const char* inColor, | 256 static const int kVarsPerBlock; |
| 247 const GrGLProcessor::TransformedCoordsArray& coords, | 257 |
| 248 const GrGLProcessor::TextureSamplerArray& samplers) =
0; | |
| 249 }; | |
| 250 | |
| 251 class GrGLFragmentProcessorEmitter : public GrGLProcessorEmitterInterface { | |
| 252 public: | |
| 253 GrGLFragmentProcessorEmitter(GrGLProgramBuilder* builder) | |
| 254 : fBuilder(builder) | |
| 255 , fFragmentProcessor(NULL) | |
| 256 , fGLFragmentProcessor(NULL) {} | |
| 257 virtual ~GrGLFragmentProcessorEmitter() {} | |
| 258 void set(const GrFragmentProcessor* fp) { | |
| 259 SkASSERT(NULL == fFragmentProcessor); | |
| 260 fFragmentProcessor = fp; | |
| 261 } | |
| 262 virtual GrGLProcessor* createGLInstance() { | |
| 263 SkASSERT(fFragmentProcessor); | |
| 264 SkASSERT(NULL == fGLFragmentProcessor); | |
| 265 fGLFragmentProcessor = | |
| 266 fFragmentProcessor->getFactory().createGLInstance(*fFragment
Processor); | |
| 267 return fGLFragmentProcessor; | |
| 268 } | |
| 269 virtual void emit(const GrProcessorKey& key, | |
| 270 const char* outColor, | |
| 271 const char* inColor, | |
| 272 const GrGLProcessor::TransformedCoordsArray& coords, | |
| 273 const GrGLProcessor::TextureSamplerArray& samplers) { | |
| 274 SkASSERT(fFragmentProcessor); | |
| 275 SkASSERT(fGLFragmentProcessor); | |
| 276 fGLFragmentProcessor->emitCode(fBuilder, *fFragmentProcessor, key, o
utColor, inColor, | |
| 277 coords, samplers); | |
| 278 // this will not leak because it hasa already been used by createGLI
nstance | |
| 279 fGLFragmentProcessor = NULL; | |
| 280 fFragmentProcessor = NULL; | |
| 281 } | |
| 282 private: | |
| 283 GrGLProgramBuilder* fBuilder; | |
| 284 const GrFragmentProcessor* fFragmentProcessor; | |
| 285 GrGLFragmentProcessor* fGLFragmentProcessor; | |
| 286 }; | |
| 287 | |
| 288 GrGLProcessorEmitterInterface* fEffectEmitter; | |
| 289 CodeStage fCodeStage; | |
| 290 SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor; | |
| 291 SkAutoTUnref<GrGLProgramEffects> fColorEffects; | |
| 292 SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; | |
| 293 BuiltinUniformHandles fUniformHandles; | 258 BuiltinUniformHandles fUniformHandles; |
| 294 bool fFragOnly; | 259 GrGLVertexShaderBuilder fVS; |
| 295 int fTexCoordSetCnt; | 260 GrGLGeometryShaderBuilder fGS; |
| 296 GrGLuint fProgramID; | |
| 297 GrGLFragmentShaderBuilder fFS; | 261 GrGLFragmentShaderBuilder fFS; |
| 298 SeparableVaryingInfoArray fSeparableVaryingInfos; | 262 bool fOutOfStage; |
| 299 | 263 int fStageIndex; |
| 300 private: | 264 |
| 301 virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor, | 265 SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor; |
| 302 const GrFragmentStage* colorStages[], | 266 SkAutoTUnref<GrGLInstalledProcessors> fColorEffects; |
| 303 const GrFragmentStage* coverageStages[], | 267 SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects; |
| 304 GrGLSLExpr4* inputColor, | 268 |
| 305 GrGLSLExpr4* inputCoverage) = 0; | 269 const GrGLProgramDesc& fDesc; |
| 306 /* | 270 GrGpuGL* fGpu; |
| 307 * Subclasses override emitEffect below to emit data and code for a specific
single effect | 271 UniformInfoArray fUniforms; |
| 308 */ | |
| 309 virtual void emitEffect(const GrProcessorStage&, | |
| 310 const GrProcessorKey&, | |
| 311 const char* outColor, | |
| 312 const char* inColor, | |
| 313 int stageIndex) = 0; | |
| 314 | |
| 315 /* | |
| 316 * Because we have fragment only builders, and those builders need to implem
ent a subclass | |
| 317 * of program effects, we have to have base classes overload the program eff
ects here | |
| 318 */ | |
| 319 virtual GrGLProgramEffects* getProgramEffects() = 0; | |
| 320 | |
| 321 /** | |
| 322 * Compiles all the shaders, links them into a program, and writes the progr
am id to the output | |
| 323 * struct. | |
| 324 **/ | |
| 325 bool finish(); | |
| 326 | |
| 327 GrGLFragmentProcessorEmitter fGrProcessorEmitter; | |
| 328 | |
| 329 const GrGLProgramDesc& fDesc; | |
| 330 GrGpuGL* fGpu; | |
| 331 UniformInfoArray fUniforms; | |
| 332 | 272 |
| 333 friend class GrGLShaderBuilder; | 273 friend class GrGLShaderBuilder; |
| 334 friend class GrGLVertexShaderBuilder; | 274 friend class GrGLVertexShaderBuilder; |
| 335 friend class GrGLFragmentShaderBuilder; | 275 friend class GrGLFragmentShaderBuilder; |
| 336 friend class GrGLGeometryShaderBuilder; | 276 friend class GrGLGeometryShaderBuilder; |
| 337 }; | 277 }; |
| 338 | 278 |
| 279 /** |
| 280 * This class encapsulates an array of GrGLProcessors and their supporting data
(coord transforms |
| 281 * and textures). It is built by GrGLProgramBuilder, then used to manage the nec
essary GL |
| 282 * state and shader uniforms in GLPrograms. Its just Plain old data, and as suc
h is entirely public |
| 283 */ |
| 284 class GrGLInstalledProcessors : public SkRefCnt { |
| 285 public: |
| 286 GrGLInstalledProcessors(int reserveCount, bool hasExplicitLocalCoords = fals
e) |
| 287 : fGLProcessors(reserveCount) |
| 288 , fSamplers(reserveCount) |
| 289 , fTransforms(reserveCount) |
| 290 , fHasExplicitLocalCoords(hasExplicitLocalCoords) { |
| 291 } |
| 292 |
| 293 virtual ~GrGLInstalledProcessors(); |
| 294 |
| 295 typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
| 296 |
| 297 struct Sampler { |
| 298 SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) |
| 299 UniformHandle fUniform; |
| 300 int fTextureUnit; |
| 301 }; |
| 302 |
| 303 class ShaderVarHandle { |
| 304 public: |
| 305 bool isValid() const { return fHandle > -1; } |
| 306 ShaderVarHandle() : fHandle(-1) {} |
| 307 ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid());
} |
| 308 int handle() const { SkASSERT(this->isValid()); return fHandle; } |
| 309 UniformHandle convertToUniformHandle() { |
| 310 SkASSERT(this->isValid()); |
| 311 return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex
(fHandle); |
| 312 } |
| 313 |
| 314 private: |
| 315 int fHandle; |
| 316 }; |
| 317 |
| 318 struct Transform { |
| 319 Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidM
atrix(); } |
| 320 ShaderVarHandle fHandle; |
| 321 SkMatrix fCurrentValue; |
| 322 GrSLType fType; |
| 323 }; |
| 324 |
| 325 void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); } |
| 326 SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); } |
| 327 SkTArray<Transform, true>& addTransforms() { return fTransforms.push_back();
} |
| 328 |
| 329 SkTArray<GrGLProcessor*> fGLProcessors; |
| 330 SkTArray<SkSTArray<4, Sampler, true> > fSamplers; |
| 331 SkTArray<SkSTArray<2, Transform, true> > fTransforms; |
| 332 bool fHasExplicitLocalCoords; |
| 333 |
| 334 typedef SkRefCnt INHERITED; |
| 335 }; |
| 336 |
| 339 #endif | 337 #endif |
| OLD | NEW |