| 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;
|
|
|