Index: src/gpu/gl/builders/GrGLProgramBuilder.h |
diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h |
index c51dcbba9f3923ac273a7f9c14a019b6bf1484da..7fa8ba266c56ad079c85a60a347ee447a4784e2e 100644 |
--- a/src/gpu/gl/builders/GrGLProgramBuilder.h |
+++ b/src/gpu/gl/builders/GrGLProgramBuilder.h |
@@ -8,25 +8,31 @@ |
#ifndef GrGLProgramBuilder_DEFINED |
#define GrGLProgramBuilder_DEFINED |
+#include "GrAllocator.h" |
+#include "GrBackendProcessorFactory.h" |
+#include "GrColor.h" |
+#include "GrProcessor.h" |
#include "GrGLFragmentShaderBuilder.h" |
#include "GrGLGeometryShaderBuilder.h" |
#include "GrGLVertexShaderBuilder.h" |
-#include "../GrGLProgramDataManager.h" |
-#include "../GrGLUniformHandle.h" |
- |
-class GrGLInstalledProcessors; |
- |
-/* |
- * This is the base class for a series of interfaces. This base class *MUST* remain abstract with |
- * NO data members because it is used in multiple interface inheritance. |
- * Heirarchy: |
- * GrGLUniformBuilder |
- * / \ |
- * GrGLFPBuilder GrGLGPBuilder |
- * \ / |
- * GrGLProgramBuilder(internal use only) |
- */ |
-class GrGLUniformBuilder { |
+#include "SkTypes.h" |
+#include "gl/GrGLProcessor.h" |
+#include "gl/GrGLProgramDesc.h" |
+#include "gl/GrGLProgramEffects.h" |
+#include "gl/GrGLSL.h" |
+#include "gl/GrGLProgramDataManager.h" |
+ |
+#include <stdarg.h> |
+ |
+class GrGLContextInfo; |
+class GrProcessorStage; |
+class GrGLProgramDesc; |
+ |
+/** |
+ Contains all the incremental state of a shader as it is being built,as well as helpers to |
+ manipulate that state. |
+*/ |
+class GrGLProgramBuilder { |
public: |
enum ShaderVisibility { |
kVertex_Visibility = 0x1, |
@@ -34,9 +40,74 @@ |
kFragment_Visibility = 0x4, |
}; |
- virtual ~GrGLUniformBuilder() {} |
- |
typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
+ typedef GrGLProgramDataManager::VaryingHandle VaryingHandle; |
+ |
+ // Handles for program uniforms (other than per-effect uniforms) |
+ struct BuiltinUniformHandles { |
+ UniformHandle fViewMatrixUni; |
+ UniformHandle fRTAdjustmentUni; |
+ UniformHandle fColorUni; |
+ UniformHandle fCoverageUni; |
+ |
+ // We use the render target height to provide a y-down frag coord when specifying |
+ // origin_upper_left is not supported. |
+ UniformHandle fRTHeightUni; |
+ |
+ // Uniforms for computing texture coords to do the dst-copy lookup |
+ UniformHandle fDstCopyTopLeftUni; |
+ UniformHandle fDstCopyScaleUni; |
+ UniformHandle fDstCopySamplerUni; |
+ }; |
+ |
+ struct UniformInfo { |
+ GrGLShaderVar fVariable; |
+ uint32_t fVisibility; |
+ GrGLint fLocation; |
+ }; |
+ |
+ // This uses an allocator rather than array so that the GrGLShaderVars don't move in memory |
+ // after they are inserted. Users of GrGLShaderBuilder get refs to the vars and ptrs to their |
+ // name strings. Otherwise, we'd have to hand out copies. |
+ typedef GrTAllocator<UniformInfo> UniformInfoArray; |
+ |
+ struct SeparableVaryingInfo { |
+ GrGLShaderVar fVariable; |
+ GrGLint fLocation; |
+ }; |
+ |
+ typedef GrTAllocator<SeparableVaryingInfo> SeparableVaryingInfoArray; |
+ |
+ /** Generates a shader program. |
+ * |
+ * The program implements what is specified in the stages given as input. |
+ * After successful generation, the builder result objects are available |
+ * to be used. |
+ * @return true if generation was successful. |
+ */ |
+ |
+ bool genProgram(const GrGeometryStage* inGeometryProcessor, |
+ const GrFragmentStage* inColorStages[], |
+ const GrFragmentStage* inCoverageStages[]); |
+ |
+ GrGLProgramEffects* getGeometryProcessor() const { |
+ SkASSERT(fProgramID); return fGeometryProcessor.get(); |
+ } |
+ GrGLProgramEffects* getColorEffects() const { SkASSERT(fProgramID); return fColorEffects.get(); } |
+ GrGLProgramEffects* getCoverageEffects() const { SkASSERT(fProgramID); return fCoverageEffects.get(); } |
+ const BuiltinUniformHandles& getBuiltinUniformHandles() const { |
+ SkASSERT(fProgramID); |
+ return fUniformHandles; |
+ } |
+ GrGLuint getProgramID() const { SkASSERT(fProgramID); return fProgramID; } |
+ bool hasVertexShader() const { SkASSERT(fProgramID); return !fFragOnly; } |
+ int getTexCoordSetCount() const { SkASSERT(fProgramID); return fTexCoordSetCnt; } |
+ const UniformInfoArray& getUniformInfos() const { return fUniforms; } |
+ const SeparableVaryingInfoArray& getSeparableVaryingInfos() const { |
+ return fSeparableVaryingInfos; |
+ } |
+ |
+ virtual ~GrGLProgramBuilder() {} |
/** Add a uniform variable to the current program, that has visibility in one or more shaders. |
visibility is a bitfield of ShaderVisibility values indicating from which shaders the |
@@ -44,297 +115,222 @@ |
supported at this time. The actual uniform name will be mangled. If outName is not NULL then |
it will refer to the final uniform name after return. Use the addUniformArray variant to add |
an array of uniforms. */ |
- virtual UniformHandle addUniform(uint32_t visibility, |
- GrSLType type, |
- const char* name, |
- const char** outName = NULL) = 0; |
- virtual UniformHandle addUniformArray(uint32_t visibility, |
- GrSLType type, |
- const char* name, |
- int arrayCount, |
- const char** outName = NULL) = 0; |
- |
- virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const = 0; |
+ GrGLProgramDataManager::UniformHandle addUniform(uint32_t visibility, |
+ GrSLType type, |
+ const char* name, |
+ const char** outName = NULL) { |
+ return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName); |
+ } |
+ GrGLProgramDataManager::UniformHandle addUniformArray(uint32_t visibility, |
+ GrSLType type, |
+ const char* name, |
+ int arrayCount, |
+ const char** outName = NULL); |
+ |
+ const GrGLShaderVar& getUniformVariable(GrGLProgramDataManager::UniformHandle u) const { |
+ return fUniforms[u.toShaderBuilderIndex()].fVariable; |
+ } |
/** |
* Shortcut for getUniformVariable(u).c_str() |
*/ |
- virtual const char* getUniformCStr(UniformHandle u) const = 0; |
- |
- virtual const GrGLContextInfo& ctxInfo() const = 0; |
- |
- virtual GrGpuGL* gpu() const = 0; |
- |
- /* |
- * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE |
- */ |
-}; |
- |
-/* a specialization of the above for GPs. Lets the user add uniforms, varyings, and VS / FS code */ |
-class GrGLGPBuilder : public virtual GrGLUniformBuilder { |
-public: |
- virtual void addVarying(GrSLType type, |
- const char* name, |
- const char** vsOutName = NULL, |
- const char** fsInName = NULL, |
- GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision) = 0; |
- |
- // TODO rename getFragmentBuilder |
- virtual GrGLGPFragmentBuilder* getFragmentShaderBuilder() = 0; |
- virtual GrGLVertexBuilder* getVertexShaderBuilder() = 0; |
- |
- /* |
- * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE |
- */ |
-}; |
- |
-/* a specializations for FPs. Lets the user add uniforms and FS code */ |
-class GrGLFPBuilder : public virtual GrGLUniformBuilder { |
-public: |
- virtual GrGLFPFragmentBuilder* getFragmentShaderBuilder() = 0; |
- |
- /* |
- * *NOTE* NO MEMBERS ALLOWED, MULTIPLE INHERITANCE |
- */ |
-}; |
- |
-/* |
- * Please note - no diamond problems because of virtual inheritance. Also, both base classes |
- * are pure virtual with no data members. This is the base class for program building. |
- * Subclasses are nearly identical but each has their own way of emitting transforms. State for |
- * each of the elements of the shader pipeline, ie vertex, fragment, geometry, etc, lives in those |
- * respective builders |
-*/ |
-class GrGLProgramBuilder : public GrGLGPBuilder, |
- public GrGLFPBuilder { |
-public: |
- /** Generates a shader program. |
- * |
- * The program implements what is specified in the stages given as input. |
- * After successful generation, the builder result objects are available |
- * to be used. |
- * @return true if generation was successful. |
- */ |
- static GrGLProgram* CreateProgram(const GrOptDrawState&, |
- const GrGLProgramDesc&, |
- GrGpu::DrawType, |
- const GrGeometryStage* inGeometryProcessor, |
- const GrFragmentStage* inColorStages[], |
- const GrFragmentStage* inCoverageStages[], |
- GrGpuGL* gpu); |
- |
- virtual UniformHandle addUniform(uint32_t visibility, |
- GrSLType type, |
- const char* name, |
- const char** outName = NULL) SK_OVERRIDE { |
- return this->addUniformArray(visibility, type, name, GrGLShaderVar::kNonArray, outName); |
- } |
- virtual UniformHandle addUniformArray(uint32_t visibility, |
- GrSLType type, |
- const char* name, |
- int arrayCount, |
- const char** outName = NULL) SK_OVERRIDE; |
- |
- virtual const GrGLShaderVar& getUniformVariable(UniformHandle u) const SK_OVERRIDE { |
- return fUniforms[u.toShaderBuilderIndex()].fVariable; |
- } |
- |
- virtual const char* getUniformCStr(UniformHandle u) const SK_OVERRIDE { |
+ const char* getUniformCStr(GrGLProgramDataManager::UniformHandle u) const { |
return this->getUniformVariable(u).c_str(); |
} |
- virtual const GrGLContextInfo& ctxInfo() const SK_OVERRIDE; |
- |
- virtual GrGpuGL* gpu() const SK_OVERRIDE { return fGpu; } |
- |
- virtual GrGLFragmentShaderBuilder* getFragmentShaderBuilder() SK_OVERRIDE { return &fFS; } |
- virtual GrGLVertexBuilder* getVertexShaderBuilder() SK_OVERRIDE { return &fVS; } |
- |
- virtual void addVarying(GrSLType type, |
- const char* name, |
- const char** vsOutName = NULL, |
- const char** fsInName = NULL, |
- GrGLShaderVar::Precision fsPrecision=GrGLShaderVar::kDefault_Precision); |
- |
- // Handles for program uniforms (other than per-effect uniforms) |
- struct BuiltinUniformHandles { |
- UniformHandle fViewMatrixUni; |
- UniformHandle fRTAdjustmentUni; |
- UniformHandle fColorUni; |
- UniformHandle fCoverageUni; |
- |
- // We use the render target height to provide a y-down frag coord when specifying |
- // origin_upper_left is not supported. |
- UniformHandle fRTHeightUni; |
- |
- // Uniforms for computing texture coords to do the dst-copy lookup |
- UniformHandle fDstCopyTopLeftUni; |
- UniformHandle fDstCopyScaleUni; |
- UniformHandle fDstCopySamplerUni; |
- }; |
+ const GrGLContextInfo& ctxInfo() const; |
+ |
+ GrGLFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; } |
+ GrGpuGL* gpu() const { return fGpu; } |
protected: |
- static GrGLProgramBuilder* CreateProgramBuilder(const GrGLProgramDesc&, |
- const GrOptDrawState&, |
- GrGpu::DrawType, |
- bool hasGeometryProcessor, |
- GrGpuGL*); |
- |
+ typedef GrTAllocator<GrGLShaderVar> VarArray; |
GrGLProgramBuilder(GrGpuGL*, const GrOptDrawState&, const GrGLProgramDesc&); |
const GrOptDrawState& optState() const { return fOptState; } |
const GrGLProgramDesc& desc() const { return fDesc; } |
- const GrGLProgramDesc::KeyHeader& header() const { return fDesc.getHeader(); } |
+ |
+ // Helper for emitEffects(). |
+ void createAndEmitEffects(const GrFragmentStage* effectStages[], |
+ int effectCnt, |
+ const GrGLProgramDesc::EffectKeyProvider&, |
+ GrGLSLExpr4* inOutFSColor); |
+ |
+ /* |
+ * A helper function called to emit the geometry processor as well as individual coverage |
+ * and color stages. this will call into subclasses emit effect |
+ */ |
+ void emitEffect(const GrProcessorStage& effectStage, |
+ int effectIndex, |
+ const GrGLProgramDesc::EffectKeyProvider& keyProvider, |
+ GrGLSLExpr4* inColor, |
+ GrGLSLExpr4* outColor); |
+ |
+ /** |
+ * Helper for emitEffect() in subclasses. Emits uniforms for an effect's texture accesses and |
+ * appends the necessary data to the TextureSamplerArray* object so effects can add texture |
+ * lookups to their code. This method is only meant to be called during the construction phase. |
+ */ |
+ void emitSamplers(const GrProcessor& effect, |
+ GrGLProcessor::TextureSamplerArray* outSamplers); |
// Generates a name for a variable. The generated string will be name prefixed by the prefix |
// char (unless the prefix is '\0'). It also mangles the name to be stage-specific if we're |
// generating stage code. |
void nameVariable(SkString* out, char prefix, const char* name); |
- void setupUniformColorAndCoverageIfNeeded(GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage); |
- void createAndEmitProcessors(const GrGeometryStage* geometryProcessor, |
- const GrFragmentStage* colorStages[], |
- const GrFragmentStage* coverageStages[], |
- GrGLSLExpr4* inputColor, |
- GrGLSLExpr4* inputCoverage); |
- template <class ProcessorStage> |
- void createAndEmitProcessors(const ProcessorStage*[], |
- int effectCnt, |
- const GrGLProgramDesc::EffectKeyProvider&, |
- GrGLSLExpr4* fsInOutColor, |
- GrGLInstalledProcessors*); |
- void verify(const GrGeometryProcessor&); |
- void verify(const GrFragmentProcessor&); |
- void emitSamplers(const GrProcessor&, |
- GrGLProcessor::TextureSamplerArray* outSamplers, |
- GrGLInstalledProcessors*); |
- |
- // each specific program builder has a distinct transform and must override this function |
- virtual void emitTransforms(const GrProcessorStage&, |
- GrGLProcessor::TransformedCoordsArray* outCoords, |
- GrGLInstalledProcessors*); |
- GrGLProgram* finalize(); |
- void bindUniformLocations(GrGLuint programID); |
- bool checkLinkStatus(GrGLuint programID); |
- void resolveUniformLocations(GrGLuint programID); |
- |
- void cleanupProgram(GrGLuint programID, const SkTDArray<GrGLuint>& shaderIDs); |
- void cleanupShaders(const SkTDArray<GrGLuint>& shaderIDs); |
- |
- // Subclasses create different programs |
- virtual GrGLProgram* createProgram(GrGLuint programID); |
- |
+ |
+ virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const; |
+ |
+ virtual void bindProgramLocations(GrGLuint programId); |
+ void resolveProgramLocations(GrGLuint programId); |
+ |
+ void appendDecls(const VarArray&, SkString*) const; |
void appendUniformDecls(ShaderVisibility, SkString*) const; |
- // reset is called by program creator between each processor's emit code. It increments the |
- // stage offset for variable name mangling, and also ensures verfication variables in the |
- // fragment shader are cleared. |
- void reset() { |
- this->enterStage(); |
- this->addStage(); |
- fFS.reset(); |
- } |
- void addStage() { fStageIndex++; } |
- |
- // This simple class exits the stage and then restores the stage when it goes out of scope |
- class AutoStageRestore { |
+ class CodeStage : SkNoncopyable { |
public: |
- AutoStageRestore(GrGLProgramBuilder* pb) |
- : fPB(pb), fOutOfStage(pb->fOutOfStage) { pb->exitStage(); } |
- ~AutoStageRestore() { fPB->fOutOfStage = fOutOfStage; } |
+ CodeStage() : fNextIndex(0), fCurrentIndex(-1), fEffectStage(NULL) {} |
+ |
+ bool inStageCode() const { |
+ this->validate(); |
+ return SkToBool(fEffectStage); |
+ } |
+ |
+ const GrProcessorStage* effectStage() const { |
+ this->validate(); |
+ return fEffectStage; |
+ } |
+ |
+ int stageIndex() const { |
+ this->validate(); |
+ return fCurrentIndex; |
+ } |
+ |
+ class AutoStageRestore : SkNoncopyable { |
+ public: |
+ AutoStageRestore(CodeStage* codeStage, const GrProcessorStage* newStage) { |
+ SkASSERT(codeStage); |
+ fSavedIndex = codeStage->fCurrentIndex; |
+ fSavedEffectStage = codeStage->fEffectStage; |
+ |
+ if (NULL == newStage) { |
+ codeStage->fCurrentIndex = -1; |
+ } else { |
+ codeStage->fCurrentIndex = codeStage->fNextIndex++; |
+ } |
+ codeStage->fEffectStage = newStage; |
+ |
+ fCodeStage = codeStage; |
+ } |
+ ~AutoStageRestore() { |
+ fCodeStage->fCurrentIndex = fSavedIndex; |
+ fCodeStage->fEffectStage = fSavedEffectStage; |
+ } |
+ private: |
+ CodeStage* fCodeStage; |
+ int fSavedIndex; |
+ const GrProcessorStage* fSavedEffectStage; |
+ }; |
private: |
- GrGLProgramBuilder* fPB; |
- bool fOutOfStage; |
- }; |
- void exitStage() { fOutOfStage = true; } |
- void enterStage() { fOutOfStage = false; } |
- int stageIndex() const { return fStageIndex; } |
- |
- typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider; |
- typedef GrGLProgramDataManager::UniformInfo UniformInfo; |
- typedef GrGLProgramDataManager::UniformInfoArray UniformInfoArray; |
- |
- // number of each input/output type in a single allocation block, used by many builders |
- static const int kVarsPerBlock; |
- |
- BuiltinUniformHandles fUniformHandles; |
- GrGLVertexBuilder fVS; |
- GrGLGeometryBuilder fGS; |
- GrGLFragmentShaderBuilder fFS; |
- bool fOutOfStage; |
- int fStageIndex; |
- |
- SkAutoTUnref<GrGLInstalledProcessors> fGeometryProcessor; |
- SkAutoTUnref<GrGLInstalledProcessors> fColorEffects; |
- SkAutoTUnref<GrGLInstalledProcessors> fCoverageEffects; |
- |
- const GrOptDrawState& fOptState; |
- const GrGLProgramDesc& fDesc; |
- GrGpuGL* fGpu; |
- UniformInfoArray fUniforms; |
- |
- friend class GrGLShaderBuilder; |
- friend class GrGLVertexBuilder; |
- friend class GrGLFragmentShaderBuilder; |
- friend class GrGLGeometryBuilder; |
-}; |
- |
-/** |
- * This class encapsulates an array of GrGLProcessors and their supporting data (coord transforms |
- * and textures). It is built by GrGLProgramBuilder, then used to manage the necessary GL |
- * state and shader uniforms in GLPrograms. Its just Plain old data, and as such is entirely public |
- * |
- * TODO We really don't need this class to have an array of processors. It makes sense for it |
- * to just have one, also break out the transforms |
- */ |
-class GrGLInstalledProcessors : public SkRefCnt { |
-public: |
- GrGLInstalledProcessors(int reserveCount, bool hasExplicitLocalCoords = false) |
- : fGLProcessors(reserveCount) |
- , fSamplers(reserveCount) |
- , fTransforms(reserveCount) |
- , fHasExplicitLocalCoords(hasExplicitLocalCoords) { |
- } |
- |
- virtual ~GrGLInstalledProcessors(); |
- |
- typedef GrGLProgramDataManager::UniformHandle UniformHandle; |
- |
- struct Sampler { |
- SkDEBUGCODE(Sampler() : fTextureUnit(-1) {}) |
- UniformHandle fUniform; |
- int fTextureUnit; |
- }; |
- |
- class ShaderVarHandle { |
+ void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); } |
+ int fNextIndex; |
+ int fCurrentIndex; |
+ const GrProcessorStage* fEffectStage; |
+ }; |
+ |
+ class GrGLProcessorEmitterInterface { |
+ public: |
+ virtual ~GrGLProcessorEmitterInterface() {} |
+ virtual GrGLProcessor* createGLInstance() = 0; |
+ virtual void emit(const GrProcessorKey& key, |
+ const char* outColor, |
+ const char* inColor, |
+ const GrGLProcessor::TransformedCoordsArray& coords, |
+ const GrGLProcessor::TextureSamplerArray& samplers) = 0; |
+ }; |
+ |
+ class GrGLFragmentProcessorEmitter : public GrGLProcessorEmitterInterface { |
public: |
- bool isValid() const { return fHandle > -1; } |
- ShaderVarHandle() : fHandle(-1) {} |
- ShaderVarHandle(int value) : fHandle(value) { SkASSERT(this->isValid()); } |
- int handle() const { SkASSERT(this->isValid()); return fHandle; } |
- UniformHandle convertToUniformHandle() { |
- SkASSERT(this->isValid()); |
- return GrGLProgramDataManager::UniformHandle::CreateFromUniformIndex(fHandle); |
- } |
- |
+ GrGLFragmentProcessorEmitter(GrGLProgramBuilder* builder) |
+ : fBuilder(builder) |
+ , fFragmentProcessor(NULL) |
+ , fGLFragmentProcessor(NULL) {} |
+ virtual ~GrGLFragmentProcessorEmitter() {} |
+ void set(const GrFragmentProcessor* fp) { |
+ SkASSERT(NULL == fFragmentProcessor); |
+ fFragmentProcessor = fp; |
+ } |
+ virtual GrGLProcessor* createGLInstance() { |
+ SkASSERT(fFragmentProcessor); |
+ SkASSERT(NULL == fGLFragmentProcessor); |
+ fGLFragmentProcessor = |
+ fFragmentProcessor->getFactory().createGLInstance(*fFragmentProcessor); |
+ return fGLFragmentProcessor; |
+ } |
+ virtual void emit(const GrProcessorKey& key, |
+ const char* outColor, |
+ const char* inColor, |
+ const GrGLProcessor::TransformedCoordsArray& coords, |
+ const GrGLProcessor::TextureSamplerArray& samplers) { |
+ SkASSERT(fFragmentProcessor); |
+ SkASSERT(fGLFragmentProcessor); |
+ fGLFragmentProcessor->emitCode(fBuilder, *fFragmentProcessor, key, outColor, inColor, |
+ coords, samplers); |
+ // this will not leak because it hasa already been used by createGLInstance |
+ fGLFragmentProcessor = NULL; |
+ fFragmentProcessor = NULL; |
+ } |
private: |
- int fHandle; |
- }; |
- |
- struct Transform { |
- Transform() : fType(kVoid_GrSLType) { fCurrentValue = SkMatrix::InvalidMatrix(); } |
- ShaderVarHandle fHandle; |
- SkMatrix fCurrentValue; |
- GrSLType fType; |
- }; |
- |
- void addEffect(GrGLProcessor* effect) { fGLProcessors.push_back(effect); } |
- SkTArray<Sampler, true>& addSamplers() { return fSamplers.push_back(); } |
- SkTArray<Transform, true>& addTransforms() { return fTransforms.push_back(); } |
- |
- SkTArray<GrGLProcessor*> fGLProcessors; |
- SkTArray<SkSTArray<4, Sampler, true> > fSamplers; |
- SkTArray<SkSTArray<2, Transform, true> > fTransforms; |
- bool fHasExplicitLocalCoords; |
+ GrGLProgramBuilder* fBuilder; |
+ const GrFragmentProcessor* fFragmentProcessor; |
+ GrGLFragmentProcessor* fGLFragmentProcessor; |
+ }; |
+ |
+ GrGLProcessorEmitterInterface* fEffectEmitter; |
+ CodeStage fCodeStage; |
+ SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor; |
+ SkAutoTUnref<GrGLProgramEffects> fColorEffects; |
+ SkAutoTUnref<GrGLProgramEffects> fCoverageEffects; |
+ BuiltinUniformHandles fUniformHandles; |
+ bool fFragOnly; |
+ int fTexCoordSetCnt; |
+ GrGLuint fProgramID; |
+ GrGLFragmentShaderBuilder fFS; |
+ SeparableVaryingInfoArray fSeparableVaryingInfos; |
+ |
+private: |
+ virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor, |
+ const GrFragmentStage* colorStages[], |
+ const GrFragmentStage* coverageStages[], |
+ GrGLSLExpr4* inputColor, |
+ GrGLSLExpr4* inputCoverage) = 0; |
+ /* |
+ * Subclasses override emitEffect below to emit data and code for a specific single effect |
+ */ |
+ virtual void emitEffect(const GrProcessorStage&, |
+ const GrProcessorKey&, |
+ const char* outColor, |
+ const char* inColor, |
+ int stageIndex) = 0; |
+ |
+ /* |
+ * Because we have fragment only builders, and those builders need to implement a subclass |
+ * of program effects, we have to have base classes overload the program effects here |
+ */ |
+ virtual GrGLProgramEffects* getProgramEffects() = 0; |
+ |
+ /** |
+ * Compiles all the shaders, links them into a program, and writes the program id to the output |
+ * struct. |
+ **/ |
+ bool finish(); |
+ |
+ GrGLFragmentProcessorEmitter fGrProcessorEmitter; |
+ |
+ const GrOptDrawState& fOptState; |
+ const GrGLProgramDesc& fDesc; |
+ GrGpuGL* fGpu; |
+ UniformInfoArray fUniforms; |
friend class GrGLShaderBuilder; |
friend class GrGLVertexShaderBuilder; |