diff options
author | 2014-09-23 09:50:21 -0700 | |
---|---|---|
committer | 2014-09-23 09:50:21 -0700 | |
commit | b0a8a377f832c59cee939ad721e1f87d378b7142 (patch) | |
tree | 7edeac33c817af28d73f3fbe1b31776ac34e8773 /src/gpu/gl/builders | |
parent | e51ac563de24ed4b25fde97c225580a30a55e9ca (diff) |
Patch to create a distinct geometry processor. The vast majority of this patch
is just a rename. The meat is in GrGeometryProcessor, GrProcessor,
GrGL*Processor, GrProcessorStage, Gr*BackendProcessorFactory,
GrProcessUnitTestFactory, and the builders
BUG=skia:
R=bsalomon@google.com
Author: joshualitt@chromium.org
Review URL: https://codereview.chromium.org/582963002
Diffstat (limited to 'src/gpu/gl/builders')
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp | 40 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h | 14 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 17 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 81 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFullProgramBuilder.cpp | 52 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFullProgramBuilder.h | 61 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.cpp | 24 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLProgramBuilder.h | 89 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLShaderBuilder.h | 12 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp | 8 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLVertexShaderBuilder.h | 2 |
11 files changed, 268 insertions, 132 deletions
diff --git a/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp index 9c32433782..2c70a75ca9 100644 --- a/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.cpp @@ -25,9 +25,9 @@ int GrGLFragmentOnlyProgramBuilder::addTexCoordSets(int count) { } void -GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(const GrEffectStage* geometryProcessor, - const GrEffectStage* colorStages[], - const GrEffectStage* coverageStages[], +GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProcessor, + const GrFragmentStage* colorStages[], + const GrFragmentStage* coverageStages[], GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) { /////////////////////////////////////////////////////////////////////////// @@ -47,9 +47,8 @@ GrGLFragmentOnlyProgramBuilder::createAndEmitEffects(const GrEffectStage* geomet } GrGLProgramEffects* GrGLFragmentOnlyProgramBuilder::onCreateAndEmitEffects( - const GrEffectStage* effectStages[], int effectCnt, + const GrFragmentStage* effectStages[], int effectCnt, const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inOutFSColor) { - fProgramEffects.reset(SkNEW_ARGS(GrGLPathTexGenProgramEffects, (effectCnt))); this->INHERITED::createAndEmitEffects(effectStages, effectCnt, @@ -58,23 +57,22 @@ GrGLProgramEffects* GrGLFragmentOnlyProgramBuilder::onCreateAndEmitEffects( return fProgramEffects.detach(); } -void GrGLFragmentOnlyProgramBuilder::emitEffect(const GrEffectStage& stage, - const GrEffectKey& key, - const char* outColor, - const char* inColor, - int stageIndex) { +void GrGLFragmentOnlyProgramBuilder::emitEffect(const GrProcessorStage& stage, + const GrProcessorKey& key, + const char* outColor, + const char* inColor, + int stageIndex) { SkASSERT(fProgramEffects.get()); - const GrEffect& effect = *stage.getEffect(); - SkASSERT(0 == effect.getVertexAttribs().count()); + const GrProcessor& effect = *stage.getProcessor(); - SkSTArray<2, GrGLEffect::TransformedCoords> coords(effect.numTransforms()); - SkSTArray<4, GrGLEffect::TextureSampler> samplers(effect.numTextures()); + SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms()); + SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures()); this->setupPathTexGen(stage, &coords); this->emitSamplers(effect, &samplers); - GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect); - SkASSERT(!glEffect->isVertexEffect()); + SkASSERT(fEffectEmitter); + GrGLProcessor* glEffect = fEffectEmitter->createGLInstance(); fProgramEffects->addEffect(glEffect); GrGLFragmentShaderBuilder* fsBuilder = this->getFragmentShaderBuilder(); @@ -83,14 +81,14 @@ void GrGLFragmentOnlyProgramBuilder::emitEffect(const GrEffectStage& stage, openBrace.printf("\t{ // Stage %d: %s\n", stageIndex, glEffect->name()); fsBuilder->codeAppend(openBrace.c_str()); - glEffect->emitCode(this, effect, key, outColor, inColor, coords, samplers); + fEffectEmitter->emit(key, outColor, inColor, coords, samplers); fsBuilder->codeAppend("\t}\n"); } -void GrGLFragmentOnlyProgramBuilder::setupPathTexGen(const GrEffectStage& effectStage, - GrGLEffect::TransformedCoordsArray* outCoords) { - int numTransforms = effectStage.getEffect()->numTransforms(); +void GrGLFragmentOnlyProgramBuilder::setupPathTexGen( + const GrProcessorStage& effectStage, GrGLProcessor::TransformedCoordsArray* outCoords) { + int numTransforms = effectStage.getProcessor()->numTransforms(); int texCoordIndex = this->addTexCoordSets(numTransforms); fProgramEffects->addTransforms(texCoordIndex); @@ -103,6 +101,6 @@ void GrGLFragmentOnlyProgramBuilder::setupPathTexGen(const GrEffectStage& effect kVec2f_GrSLType; name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++); - SkNEW_APPEND_TO_TARRAY(outCoords, GrGLEffect::TransformedCoords, (name, type)); + SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, (name, type)); } } diff --git a/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h b/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h index 291669c0a8..b1fb88d954 100644 --- a/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentOnlyProgramBuilder.h @@ -17,19 +17,19 @@ public: int addTexCoordSets(int count); private: - virtual void createAndEmitEffects(const GrEffectStage* geometryProcessor, - const GrEffectStage* colorStages[], - const GrEffectStage* coverageStages[], + virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor, + const GrFragmentStage* colorStages[], + const GrFragmentStage* coverageStages[], GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) SK_OVERRIDE; - GrGLProgramEffects* onCreateAndEmitEffects(const GrEffectStage* effectStages[], + GrGLProgramEffects* onCreateAndEmitEffects(const GrFragmentStage* effectStages[], int effectCnt, const GrGLProgramDesc::EffectKeyProvider&, GrGLSLExpr4* inOutFSColor); - virtual void emitEffect(const GrEffectStage& stage, - const GrEffectKey& key, + virtual void emitEffect(const GrProcessorStage& stage, + const GrProcessorKey& key, const char* outColor, const char* inColor, int stageIndex) SK_OVERRIDE; @@ -42,7 +42,7 @@ private: * types are appended to the TransformedCoordsArray* object, which is in turn passed to the * effect's emitCode() function. */ - void setupPathTexGen(const GrEffectStage&, GrGLEffect::TransformedCoordsArray*); + void setupPathTexGen(const GrProcessorStage&, GrGLProcessor::TransformedCoordsArray*); virtual GrGLProgramEffects* getProgramEffects() SK_OVERRIDE { return fProgramEffects.get(); } diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp index 7279f1c393..4266d9fc43 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp @@ -80,9 +80,13 @@ GrGLFragmentShaderBuilder::GrGLFragmentShaderBuilder(GrGLProgramBuilder* program const char* GrGLFragmentShaderBuilder::dstColor() { if (fProgramBuilder->fCodeStage.inStageCode()) { - const GrEffect* effect = fProgramBuilder->fCodeStage.effectStage()->getEffect(); - if (!effect->willReadDstColor()) { - SkDEBUGFAIL("GrGLEffect asked for dst color but its generating GrEffect " + const GrProcessor* effect = fProgramBuilder->fCodeStage.effectStage()->getProcessor(); + // TODO GPs can't read dst color, and full program builder only returns a pointer to the + // base fragment shader builder which does not have this function. Unfortunately, + // the code stage class only has a GrProcessor pointer so this is required for the time + // being + if (!static_cast<const GrFragmentProcessor*>(effect)->willReadDstColor()) { + SkDEBUGFAIL("GrGLProcessor asked for dst color but its generating GrProcessor " "did not request access."); return ""; } @@ -119,7 +123,8 @@ bool GrGLFragmentShaderBuilder::enableFeature(GLSLFeature feature) { } } -SkString GrGLFragmentShaderBuilder::ensureFSCoords2D(const TransformedCoordsArray& coords, int index) { +SkString GrGLFragmentShaderBuilder::ensureFSCoords2D( + const GrGLProcessor::TransformedCoordsArray& coords, int index) { if (kVec3f_GrSLType != coords[index].getType()) { SkASSERT(kVec2f_GrSLType == coords[index].getType()); return coords[index].getName(); @@ -137,9 +142,9 @@ SkString GrGLFragmentShaderBuilder::ensureFSCoords2D(const TransformedCoordsArra const char* GrGLFragmentShaderBuilder::fragmentPosition() { GrGLProgramBuilder::CodeStage* cs = &fProgramBuilder->fCodeStage; if (cs->inStageCode()) { - const GrEffect* effect = cs->effectStage()->getEffect(); + const GrProcessor* effect = cs->effectStage()->getProcessor(); if (!effect->willReadFragmentPosition()) { - SkDEBUGFAIL("GrGLEffect asked for frag position but its generating GrEffect " + SkDEBUGFAIL("GrGLProcessor asked for frag position but its generating GrProcessor " "did not request access."); return ""; } diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index b3e0ab0405..38d569e734 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -11,27 +11,14 @@ class GrGLProgramBuilder; -class GrGLFragmentShaderBuilder : public GrGLShaderBuilder { +/* + * This base class encapsulates the functionality which all GrProcessors are allowed to use in their + * fragment shader + */ +class GrGLProcessorFragmentShaderBuilder : public GrGLShaderBuilder { public: - typedef uint8_t DstReadKey; - typedef uint8_t FragPosKey; - - /** Returns a key for adding code to read the copy-of-dst color in service of effects that - require reading the dst. It must not return 0 because 0 indicates that there is no dst - copy read at all (in which case this function should not be called). */ - static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&); - - /** Returns a key for reading the fragment location. This should only be called if there is an - effect that will requires the fragment position. If the fragment position is not required, - the key is 0. */ - static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&); - - GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, const GrGLProgramDesc& desc); - - /** Returns the variable name that holds the color of the destination pixel. This may be NULL if - no effect advertised that it will read the destination. */ - const char* dstColor(); - + GrGLProcessorFragmentShaderBuilder(GrGLProgramBuilder* program) : INHERITED(program) {} + virtual ~GrGLProcessorFragmentShaderBuilder() {} /** * Use of these features may require a GLSL extension to be enabled. Shaders may not compile * if code is added that uses one of these features without calling enableFeature() @@ -45,19 +32,65 @@ public: * If the feature is supported then true is returned and any necessary #extension declarations * are added to the shaders. If the feature is not supported then false will be returned. */ - bool enableFeature(GLSLFeature); + virtual bool enableFeature(GLSLFeature) = 0; /** * This returns a variable name to access the 2D, perspective correct version of the coords in * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a * perspective divide into the fragment shader (xy / z) to convert them to 2D. */ - SkString ensureFSCoords2D(const TransformedCoordsArray& coords, int index); + virtual SkString ensureFSCoords2D(const GrGLProcessor::TransformedCoordsArray& coords, + int index) = 0; /** Returns a variable name that represents the position of the fragment in the FS. The position is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */ - const char* fragmentPosition(); + virtual const char* fragmentPosition() = 0; + +private: + typedef GrGLShaderBuilder INHERITED; +}; + +/* + * Fragment processor's, in addition to all of the above, may need to use dst color so they use + * this builder to create their shader + */ +class GrGLFragmentProcessorShaderBuilder : public GrGLProcessorFragmentShaderBuilder { +public: + GrGLFragmentProcessorShaderBuilder(GrGLProgramBuilder* program) : INHERITED(program) {} + /** Returns the variable name that holds the color of the destination pixel. This may be NULL if + no effect advertised that it will read the destination. */ + virtual const char* dstColor() = 0; + +private: + typedef GrGLProcessorFragmentShaderBuilder INHERITED; +}; + +class GrGLFragmentShaderBuilder : public GrGLFragmentProcessorShaderBuilder { +public: + typedef uint8_t DstReadKey; + typedef uint8_t FragPosKey; + + /** Returns a key for adding code to read the copy-of-dst color in service of effects that + require reading the dst. It must not return 0 because 0 indicates that there is no dst + copy read at all (in which case this function should not be called). */ + static DstReadKey KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps&); + + /** Returns a key for reading the fragment location. This should only be called if there is an + effect that will requires the fragment position. If the fragment position is not required, + the key is 0. */ + static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst, const GrGLCaps&); + + GrGLFragmentShaderBuilder(GrGLProgramBuilder* program, const GrGLProgramDesc& desc); + + virtual const char* dstColor() SK_OVERRIDE; + + virtual bool enableFeature(GLSLFeature) SK_OVERRIDE; + + virtual SkString ensureFSCoords2D(const GrGLProcessor::TransformedCoordsArray& coords, + int index) SK_OVERRIDE; + + virtual const char* fragmentPosition() SK_OVERRIDE; private: /* @@ -113,7 +146,7 @@ private: friend class GrGLProgramBuilder; friend class GrGLFullProgramBuilder; - typedef GrGLShaderBuilder INHERITED; + typedef GrGLFragmentProcessorShaderBuilder INHERITED; }; #endif diff --git a/src/gpu/gl/builders/GrGLFullProgramBuilder.cpp b/src/gpu/gl/builders/GrGLFullProgramBuilder.cpp index dd6409e6fd..46db712a96 100644 --- a/src/gpu/gl/builders/GrGLFullProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFullProgramBuilder.cpp @@ -10,16 +10,17 @@ #include "../GrGpuGL.h" GrGLFullProgramBuilder::GrGLFullProgramBuilder(GrGpuGL* gpu, - const GrGLProgramDesc& desc) + const GrGLProgramDesc& desc) : INHERITED(gpu, desc) + , fGLGeometryProcessorEmitter(this) , fGS(this) , fVS(this) { } void -GrGLFullProgramBuilder::createAndEmitEffects(const GrEffectStage* geometryProcessor, - const GrEffectStage* colorStages[], - const GrEffectStage* coverageStages[], +GrGLFullProgramBuilder::createAndEmitEffects(const GrGeometryStage* geometryProcessor, + const GrFragmentStage* colorStages[], + const GrFragmentStage* coverageStages[], GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) { fVS.emitCodeBeforeEffects(inputColor, inputCoverage); @@ -27,7 +28,6 @@ GrGLFullProgramBuilder::createAndEmitEffects(const GrEffectStage* geometryProces /////////////////////////////////////////////////////////////////////////// // emit the per-effect code for both color and coverage effects - bool useLocalCoords = this->getVertexShaderBuilder()->hasExplicitLocalCoords(); EffectKeyProvider colorKeyProvider(&this->desc(), EffectKeyProvider::kColor_EffectType); fColorEffects.reset(this->onCreateAndEmitEffects(colorStages, this->desc().numColorEffects(), @@ -35,10 +35,15 @@ GrGLFullProgramBuilder::createAndEmitEffects(const GrEffectStage* geometryProces inputColor)); if (geometryProcessor) { + const GrGeometryProcessor& gp = *geometryProcessor->getGeometryProcessor(); + fGLGeometryProcessorEmitter.set(&gp); + fEffectEmitter = &fGLGeometryProcessorEmitter; + fVS.emitAttributes(gp); GrGLSLExpr4 gpInputCoverage = *inputCoverage; GrGLSLExpr4 gpOutputCoverage; EffectKeyProvider gpKeyProvider(&this->desc(), EffectKeyProvider::kGeometryProcessor_EffectType); + bool useLocalCoords = this->getVertexShaderBuilder()->hasExplicitLocalCoords(); fProgramEffects.reset(SkNEW_ARGS(GrGLVertexProgramEffects, (1, useLocalCoords))); this->INHERITED::emitEffect(*geometryProcessor, 0, gpKeyProvider, &gpInputCoverage, &gpOutputCoverage); @@ -86,7 +91,7 @@ GrGLFullProgramBuilder::addSeparableVarying(GrSLType type, } GrGLProgramEffects* GrGLFullProgramBuilder::onCreateAndEmitEffects( - const GrEffectStage* effectStages[], + const GrFragmentStage* effectStages[], int effectCnt, const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inOutFSColor) { @@ -100,21 +105,21 @@ GrGLProgramEffects* GrGLFullProgramBuilder::onCreateAndEmitEffects( return fProgramEffects.detach(); } -void GrGLFullProgramBuilder::emitEffect(const GrEffectStage& stage, - const GrEffectKey& key, - const char* outColor, - const char* inColor, - int stageIndex) { +void GrGLFullProgramBuilder::emitEffect(const GrProcessorStage& stage, + const GrProcessorKey& key, + const char* outColor, + const char* inColor, + int stageIndex) { SkASSERT(fProgramEffects.get()); - const GrEffect& effect = *stage.getEffect(); - SkSTArray<2, GrGLEffect::TransformedCoords> coords(effect.numTransforms()); - SkSTArray<4, GrGLEffect::TextureSampler> samplers(effect.numTextures()); + const GrProcessor& effect = *stage.getProcessor(); + SkSTArray<2, GrGLProcessor::TransformedCoords> coords(effect.numTransforms()); + SkSTArray<4, GrGLProcessor::TextureSampler> samplers(effect.numTextures()); - fVS.emitAttributes(stage); this->emitTransforms(stage, &coords); this->emitSamplers(effect, &samplers); - GrGLEffect* glEffect = effect.getFactory().createGLInstance(effect); + SkASSERT(fEffectEmitter); + GrGLProcessor* glEffect = fEffectEmitter->createGLInstance(); fProgramEffects->addEffect(glEffect); // Enclose custom code in a block to avoid namespace conflicts @@ -123,22 +128,17 @@ void GrGLFullProgramBuilder::emitEffect(const GrEffectStage& stage, fFS.codeAppend(openBrace.c_str()); fVS.codeAppend(openBrace.c_str()); - if (glEffect->isVertexEffect()) { - GrGLGeometryProcessor* vertexEffect = static_cast<GrGLGeometryProcessor*>(glEffect); - vertexEffect->emitCode(this, effect, key, outColor, inColor, coords, samplers); - } else { - glEffect->emitCode(this, effect, key, outColor, inColor, coords, samplers); - } + fEffectEmitter->emit(key, outColor, inColor, coords, samplers); fVS.codeAppend("\t}\n"); fFS.codeAppend("\t}\n"); } -void GrGLFullProgramBuilder::emitTransforms(const GrEffectStage& effectStage, - GrGLEffect::TransformedCoordsArray* outCoords) { +void GrGLFullProgramBuilder::emitTransforms(const GrProcessorStage& effectStage, + GrGLProcessor::TransformedCoordsArray* outCoords) { SkTArray<GrGLVertexProgramEffects::Transform, true>& transforms = fProgramEffects->addTransforms(); - const GrEffect* effect = effectStage.getEffect(); + const GrProcessor* effect = effectStage.getProcessor(); int numTransforms = effect->numTransforms(); transforms.push_back_n(numTransforms); @@ -199,7 +199,7 @@ void GrGLFullProgramBuilder::emitTransforms(const GrEffectStage& effectStage, fVS.codeAppendf("%s = %s * vec3(%s, 1);", vsVaryingName, uniName, coords.c_str()); } - SkNEW_APPEND_TO_TARRAY(outCoords, GrGLEffect::TransformedCoords, + SkNEW_APPEND_TO_TARRAY(outCoords, GrGLProcessor::TransformedCoords, (SkString(fsVaryingName), varyingType)); } } diff --git a/src/gpu/gl/builders/GrGLFullProgramBuilder.h b/src/gpu/gl/builders/GrGLFullProgramBuilder.h index 7480ff3858..41da17ff9e 100644 --- a/src/gpu/gl/builders/GrGLFullProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLFullProgramBuilder.h @@ -9,6 +9,7 @@ #define GrGLFullProgramBuilder_DEFINED #include "GrGLProgramBuilder.h" +#include "../GrGLGeometryProcessor.h" class GrGLVertexProgramEffects; @@ -38,20 +39,63 @@ public: GrGLVertexShaderBuilder* getVertexShaderBuilder() { return &fVS; } + /* + * This non-virtual call will hide the parent call to prevent GPs from accessing fragment shader + * functionality they shouldn't be using + */ + GrGLProcessorFragmentShaderBuilder* getFragmentShaderBuilder() { return &fFS; } + private: - virtual void createAndEmitEffects(const GrEffectStage* geometryProcessor, - const GrEffectStage* colorStages[], - const GrEffectStage* coverageStages[], + virtual void createAndEmitEffects(const GrGeometryStage* geometryProcessor, + const GrFragmentStage* colorStages[], + const GrFragmentStage* coverageStages[], GrGLSLExpr4* inputColor, GrGLSLExpr4* inputCoverage) SK_OVERRIDE; - GrGLProgramEffects* onCreateAndEmitEffects(const GrEffectStage* effectStages[], + GrGLProgramEffects* onCreateAndEmitEffects(const GrFragmentStage* effectStages[], int effectCnt, const GrGLProgramDesc::EffectKeyProvider&, GrGLSLExpr4* inOutFSColor); - virtual void emitEffect(const GrEffectStage& stage, - const GrEffectKey& key, + class GrGLGeometryProcessorEmitter : public GrGLProgramBuilder::GrGLProcessorEmitterInterface { + public: + GrGLGeometryProcessorEmitter(GrGLFullProgramBuilder* builder) + : fBuilder(builder) + , fGeometryProcessor(NULL) + , fGLGeometryProcessor(NULL) {} + virtual ~GrGLGeometryProcessorEmitter() {} + void set(const GrGeometryProcessor* gp) { + SkASSERT(NULL == fGeometryProcessor); + fGeometryProcessor = gp; + } + virtual GrGLProcessor* createGLInstance() { + SkASSERT(fGeometryProcessor); + SkASSERT(NULL == fGLGeometryProcessor); + fGLGeometryProcessor = + fGeometryProcessor->getFactory().createGLInstance(*fGeometryProcessor); + return fGLGeometryProcessor; + } + virtual void emit(const GrProcessorKey& key, + const char* outColor, + const char* inColor, + const GrGLProcessor::TransformedCoordsArray& coords, + const GrGLProcessor::TextureSamplerArray& samplers) { + SkASSERT(fGeometryProcessor); + SkASSERT(fGLGeometryProcessor); + fGLGeometryProcessor->emitCode(fBuilder, *fGeometryProcessor, key, outColor, + inColor, coords, samplers); + // this will not leak because it has already been used by createGLInstance + fGLGeometryProcessor = NULL; + fGeometryProcessor = NULL; + } + private: + GrGLFullProgramBuilder* fBuilder; + const GrGeometryProcessor* fGeometryProcessor; + GrGLGeometryProcessor* fGLGeometryProcessor; + }; + + virtual void emitEffect(const GrProcessorStage& stage, + const GrProcessorKey& key, const char* outColor, const char* inColor, int stageIndex) SK_OVERRIDE; @@ -63,8 +107,8 @@ private: * of the varyings in the VS and FS as well their types are appended to the * TransformedCoordsArray* object, which is in turn passed to the effect's emitCode() function. */ - void emitTransforms(const GrEffectStage& effectStage, - GrGLEffect::TransformedCoordsArray* outCoords); + void emitTransforms(const GrProcessorStage& effectStage, + GrGLProcessor::TransformedCoordsArray* outCoords); virtual bool compileAndAttachShaders(GrGLuint programId, SkTDArray<GrGLuint>* shaderIds) const SK_OVERRIDE; @@ -75,6 +119,7 @@ private: typedef GrGLProgramDesc::EffectKeyProvider EffectKeyProvider; + GrGLGeometryProcessorEmitter fGLGeometryProcessorEmitter; GrGLGeometryShaderBuilder fGS; GrGLVertexShaderBuilder fVS; SkAutoTDelete<GrGLVertexProgramEffects> fProgramEffects; diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.cpp b/src/gpu/gl/builders/GrGLProgramBuilder.cpp index 328243d954..909ac76d62 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.cpp +++ b/src/gpu/gl/builders/GrGLProgramBuilder.cpp @@ -30,9 +30,9 @@ static const GrGLShaderVar::Precision kDefaultFragmentPrecision = GrGLShaderVar: /////////////////////////////////////////////////////////////////////////////////////////////////// -bool GrGLProgramBuilder::genProgram(const GrEffectStage* geometryProcessor, - const GrEffectStage* colorStages[], - const GrEffectStage* coverageStages[]) { +bool GrGLProgramBuilder::genProgram(const GrGeometryStage* geometryProcessor, + const GrFragmentStage* colorStages[], + const GrFragmentStage* coverageStages[]) { const GrGLProgramDesc::KeyHeader& header = this->desc().getHeader(); fFS.emitCodeBeforeEffects(); @@ -84,11 +84,13 @@ bool GrGLProgramBuilder::genProgram(const GrEffectStage* geometryProcessor, GrGLProgramBuilder::GrGLProgramBuilder(GrGpuGL* gpu, const GrGLProgramDesc& desc) - : fFragOnly(SkToBool(desc.getHeader().fUseFragShaderOnly)) + : fEffectEmitter(NULL) + , fFragOnly(SkToBool(desc.getHeader().fUseFragShaderOnly)) , fTexCoordSetCnt(0) , fProgramID(0) , fFS(this, desc) , fSeparableVaryingInfos(kVarsPerBlock) + , fGrProcessorEmitter(this) , fDesc(desc) , fGpu(gpu) , fUniforms(kVarsPerBlock) { @@ -157,7 +159,7 @@ void GrGLProgramBuilder::appendUniformDecls(ShaderVisibility visibility, } } -void GrGLProgramBuilder::createAndEmitEffects(const GrEffectStage* effectStages[], +void GrGLProgramBuilder::createAndEmitEffects(const GrFragmentStage* effectStages[], int effectCnt, const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* fsInOutColor) { @@ -167,6 +169,8 @@ void GrGLProgramBuilder::createAndEmitEffects(const GrEffectStage* effectStages[ GrGLSLExpr4 outColor; for (int e = 0; e < effectCnt; ++e) { + fGrProcessorEmitter.set(effectStages[e]->getFragmentProcessor()); + fEffectEmitter = &fGrProcessorEmitter; // calls into the subclass to emit the actual effect into the program effect object this->emitEffect(*effectStages[e], e, keyProvider, &inColor, &outColor); effectEmitted = true; @@ -177,12 +181,12 @@ void GrGLProgramBuilder::createAndEmitEffects(const GrEffectStage* effectStages[ } } -void GrGLProgramBuilder::emitEffect(const GrEffectStage& effectStage, +void GrGLProgramBuilder::emitEffect(const GrProcessorStage& effectStage, int effectIndex, const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inColor, GrGLSLExpr4* outColor) { - SkASSERT(effectStage.getEffect()); + SkASSERT(effectStage.getProcessor()); CodeStage::AutoStageRestore csar(&fCodeStage, &effectStage); if (inColor->isZeros()) { @@ -206,8 +210,8 @@ void GrGLProgramBuilder::emitEffect(const GrEffectStage& effectStage, *inColor = *outColor; } -void GrGLProgramBuilder::emitSamplers(const GrEffect& effect, - GrGLEffect::TextureSamplerArray* outSamplers) { +void GrGLProgramBuilder::emitSamplers(const GrProcessor& effect, + GrGLProcessor::TextureSamplerArray* outSamplers) { SkTArray<GrGLProgramEffects::Sampler, true>& samplers = this->getProgramEffects()->addSamplers(); int numTextures = effect.numTextures(); @@ -218,7 +222,7 @@ void GrGLProgramBuilder::emitSamplers(const GrEffect& effect, samplers[t].fUniform = this->addUniform(GrGLProgramBuilder::kFragment_Visibility, kSampler2D_GrSLType, name.c_str()); - SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLEffect::TextureSampler, + SkNEW_APPEND_TO_TARRAY(outSamplers, GrGLProcessor::TextureSampler, (samplers[t].fUniform, effect.textureAccess(t))); } } diff --git a/src/gpu/gl/builders/GrGLProgramBuilder.h b/src/gpu/gl/builders/GrGLProgramBuilder.h index 9f8defb6dd..f6397d8871 100644 --- a/src/gpu/gl/builders/GrGLProgramBuilder.h +++ b/src/gpu/gl/builders/GrGLProgramBuilder.h @@ -9,13 +9,14 @@ #define GrGLProgramBuilder_DEFINED #include "GrAllocator.h" -#include "GrBackendEffectFactory.h" +#include "GrBackendProcessorFactory.h" #include "GrColor.h" -#include "GrEffect.h" +#include "GrProcessor.h" #include "GrGLFragmentShaderBuilder.h" #include "GrGLGeometryShaderBuilder.h" #include "GrGLVertexShaderBuilder.h" #include "SkTypes.h" +#include "gl/GrGLProcessor.h" #include "gl/GrGLProgramDesc.h" #include "gl/GrGLProgramEffects.h" #include "gl/GrGLSL.h" @@ -24,7 +25,7 @@ #include <stdarg.h> class GrGLContextInfo; -class GrEffectStage; +class GrProcessorStage; class GrGLProgramDesc; /** @@ -85,9 +86,9 @@ public: * @return true if generation was successful. */ - bool genProgram(const GrEffectStage* inGeometryProcessor, - const GrEffectStage* inColorStages[], - const GrEffectStage* inCoverageStages[]); + bool genProgram(const GrGeometryStage* inGeometryProcessor, + const GrFragmentStage* inColorStages[], + const GrFragmentStage* inCoverageStages[]); GrGLProgramEffects* getGeometryProcessor() const { SkASSERT(fProgramID); return fGeometryProcessor.get(); @@ -149,7 +150,7 @@ protected: const GrGLProgramDesc& desc() const { return fDesc; } // Helper for emitEffects(). - void createAndEmitEffects(const GrEffectStage* effectStages[], + void createAndEmitEffects(const GrFragmentStage* effectStages[], int effectCnt, const GrGLProgramDesc::EffectKeyProvider&, GrGLSLExpr4* inOutFSColor); @@ -158,7 +159,7 @@ protected: * 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 GrEffectStage& effectStage, + void emitEffect(const GrProcessorStage& effectStage, int effectIndex, const GrGLProgramDesc::EffectKeyProvider& keyProvider, GrGLSLExpr4* inColor, @@ -169,7 +170,8 @@ protected: * 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 GrEffect& effect, GrGLEffect::TextureSamplerArray* outSamplers); + 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 @@ -193,7 +195,7 @@ protected: return SkToBool(fEffectStage); } - const GrEffectStage* effectStage() const { + const GrProcessorStage* effectStage() const { this->validate(); return fEffectStage; } @@ -205,7 +207,7 @@ protected: class AutoStageRestore : SkNoncopyable { public: - AutoStageRestore(CodeStage* codeStage, const GrEffectStage* newStage) { + AutoStageRestore(CodeStage* codeStage, const GrProcessorStage* newStage) { SkASSERT(codeStage); fSavedIndex = codeStage->fCurrentIndex; fSavedEffectStage = codeStage->fEffectStage; @@ -226,15 +228,64 @@ protected: private: CodeStage* fCodeStage; int fSavedIndex; - const GrEffectStage* fSavedEffectStage; + const GrProcessorStage* fSavedEffectStage; }; private: void validate() const { SkASSERT((NULL == fEffectStage) == (-1 == fCurrentIndex)); } int fNextIndex; int fCurrentIndex; - const GrEffectStage* fEffectStage; + 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: + 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: + GrGLProgramBuilder* fBuilder; + const GrFragmentProcessor* fFragmentProcessor; + GrGLFragmentProcessor* fGLFragmentProcessor; + }; + + GrGLProcessorEmitterInterface* fEffectEmitter; CodeStage fCodeStage; SkAutoTUnref<GrGLProgramEffects> fGeometryProcessor; SkAutoTUnref<GrGLProgramEffects> fColorEffects; @@ -247,16 +298,16 @@ protected: SeparableVaryingInfoArray fSeparableVaryingInfos; private: - virtual void createAndEmitEffects(const GrEffectStage* geometryProcessor, - const GrEffectStage* colorStages[], - const GrEffectStage* coverageStages[], + 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 GrEffectStage&, - const GrEffectKey&, + virtual void emitEffect(const GrProcessorStage&, + const GrProcessorKey&, const char* outColor, const char* inColor, int stageIndex) = 0; @@ -273,6 +324,8 @@ private: **/ bool finish(); + GrGLFragmentProcessorEmitter fGrProcessorEmitter; + const GrGLProgramDesc& fDesc; GrGpuGL* fGpu; UniformInfoArray fUniforms; diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.h b/src/gpu/gl/builders/GrGLShaderBuilder.h index 45d3d1ee3c..e99fcce747 100644 --- a/src/gpu/gl/builders/GrGLShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLShaderBuilder.h @@ -12,15 +12,15 @@ #include "gl/GrGLProgramEffects.h" #include "gl/GrGLSL.h" #include "gl/GrGLProgramDataManager.h" -#include "GrBackendEffectFactory.h" +#include "GrBackendProcessorFactory.h" #include "GrColor.h" -#include "GrEffect.h" +#include "GrProcessor.h" #include "SkTypes.h" #include <stdarg.h> class GrGLContextInfo; -class GrEffectStage; +class GrProcessorStage; class GrGLProgramDesc; class GrGLProgramBuilder; class GrGLFullProgramBuilder; @@ -30,8 +30,8 @@ class GrGLFullProgramBuilder; */ class GrGLShaderBuilder { public: - typedef GrGLEffect::TransformedCoordsArray TransformedCoordsArray; - typedef GrGLEffect::TextureSampler TextureSampler; + typedef GrGLProcessor::TransformedCoordsArray TransformedCoordsArray; + typedef GrGLProcessor::TextureSampler TextureSampler; GrGLShaderBuilder(GrGLProgramBuilder* program); void addInput(GrGLShaderVar i) { fInputs.push_back(i); } @@ -75,7 +75,7 @@ public: static const GrGLenum* GetTexParamSwizzle(GrPixelConfig config, const GrGLCaps& caps); /** - * Called by GrGLEffects to add code to one of the shaders. + * Called by GrGLProcessors to add code to one of the shaders. */ void codeAppendf(const char format[], ...) SK_PRINTF_LIKE(2, 3) { va_list args; diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp index f99791e24e..4877071d77 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.cpp @@ -37,10 +37,8 @@ bool GrGLVertexShaderBuilder::addAttribute(const GrShaderVar& var) { return true; } -void GrGLVertexShaderBuilder::emitAttributes(const GrEffectStage& stage) { - const GrEffect& effect = *stage.getEffect(); - const GrEffect::VertexAttribArray& vars = - effect.getVertexAttribs(); +void GrGLVertexShaderBuilder::emitAttributes(const GrGeometryProcessor& gp) { + const GrGeometryProcessor::VertexAttribArray& vars = gp.getVertexAttribs(); int numAttributes = vars.count(); for (int a = 0; a < numAttributes; ++a) { this->addAttribute(vars[a]); @@ -95,7 +93,7 @@ void GrGLVertexShaderBuilder::bindProgramLocations(GrGLuint programId) { int i = fEffectAttribOffset; for (int index = 0; index < vaCount; index++) { - if (kEffect_GrVertexAttribBinding != vaPtr[index].fBinding) { + if (kGeometryProcessor_GrVertexAttribBinding != vaPtr[index].fBinding) { continue; } SkASSERT(index != header.fPositionAttributeIndex && diff --git a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h index 434e7e63c6..c93b3be668 100644 --- a/src/gpu/gl/builders/GrGLVertexShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLVertexShaderBuilder.h @@ -18,7 +18,7 @@ public: /* * this call is only for GrGLProgramEffects' internal use */ - void emitAttributes(const GrEffectStage& stage); + void emitAttributes(const GrGeometryProcessor& gp); /** * Are explicit local coordinates provided as input to the vertex shader. |