diff options
author | tomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-24 15:10:14 +0000 |
---|---|---|
committer | tomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-05-24 15:10:14 +0000 |
commit | 6a820b652e2cbd9e1c7ee2885993b0ffd331c040 (patch) | |
tree | 6e102d8c489419cff499c2e6dec14db9cc790168 /src | |
parent | 8137fcfa7de5132d0358ace615f1e073fe48a7f2 (diff) |
First stage of reworking custom shader infrastructure to allow
radial mappings.
http://codereview.appspot.com/6239043/
git-svn-id: http://skia.googlecode.com/svn/trunk@4040 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/effects/GrConvolutionEffect.cpp | 35 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgram.cpp | 148 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.cpp | 23 | ||||
-rw-r--r-- | src/gpu/gl/GrGLProgramStage.h | 46 | ||||
-rw-r--r-- | src/gpu/gl/GrGpuGLShaders.cpp | 3 |
5 files changed, 145 insertions, 110 deletions
diff --git a/src/gpu/effects/GrConvolutionEffect.cpp b/src/gpu/effects/GrConvolutionEffect.cpp index 29d1573061..8ccf5859e4 100644 --- a/src/gpu/effects/GrConvolutionEffect.cpp +++ b/src/gpu/effects/GrConvolutionEffect.cpp @@ -21,23 +21,24 @@ public: const GrCustomStage* stage); virtual void setupVSUnis(VarArray* vsUnis, int stage) SK_OVERRIDE; virtual void setupFSUnis(VarArray* fsUnis, int stage) SK_OVERRIDE; - virtual void emitVS(GrStringBuilder* code, + virtual void emitVS(GrGLShaderBuilder* state, const char* vertexCoords) SK_OVERRIDE; - virtual void emitFS(GrStringBuilder* code, + virtual void emitFS(GrGLShaderBuilder* state, const char* outputColor, const char* inputColor, - const char* samplerName, - const char* sampleCoords) SK_OVERRIDE; + const char* samplerName) SK_OVERRIDE; virtual void initUniforms(const GrGLInterface*, int programID) SK_OVERRIDE; - virtual void setData(const GrGLInterface*, const GrCustomStage*, - const GrGLTexture*) SK_OVERRIDE; + virtual void setData(const GrGLInterface*, + const GrGLTexture&, + GrCustomStage*, + int stageNum) SK_OVERRIDE; static inline StageKey GenKey(const GrCustomStage* s); protected: - int fKernelWidth; + unsigned int fKernelWidth; GrGLShaderVar* fKernelVar; GrGLShaderVar* fImageIncrementVar; @@ -89,8 +90,9 @@ void GrGLConvolutionEffect::setupFSUnis(VarArray* fsUnis, fsUnis->push_back(*fImageIncrementVar).setEmitPrecision(false); } -void GrGLConvolutionEffect::emitVS(GrStringBuilder* code, +void GrGLConvolutionEffect::emitVS(GrGLShaderBuilder* state, const char* vertexCoords) { + GrStringBuilder* code = &state->fVSCode; float scale = (fKernelWidth - 1) * 0.5f; code->appendf("\t\t%s -= vec2(%g, %g) * %s;\n", vertexCoords, scale, scale, @@ -98,11 +100,11 @@ void GrGLConvolutionEffect::emitVS(GrStringBuilder* code, } -void GrGLConvolutionEffect::emitFS(GrStringBuilder* code, +void GrGLConvolutionEffect::emitFS(GrGLShaderBuilder* state, const char* outputColor, const char* inputColor, - const char* samplerName, - const char* sampleCoords) { + const char* samplerName) { + GrStringBuilder* code = &state->fFSCode; const char* texFunc = "texture2D"; bool complexCoord = false; @@ -117,7 +119,7 @@ void GrGLConvolutionEffect::emitFS(GrStringBuilder* code, fKernelVar->appendArrayAccess("i", &kernelIndex); code->appendf("\t\tvec4 sum = vec4(0, 0, 0, 0);\n"); - code->appendf("\t\tvec2 coord = %s;\n", sampleCoords); + code->appendf("\t\tvec2 coord = %s;\n", state->fSampleCoords.c_str()); code->appendf("\t\tfor (int i = 0; i < %d; i++) {\n", fKernelWidth); @@ -141,8 +143,9 @@ void GrGLConvolutionEffect::initUniforms(const GrGLInterface* gl, } void GrGLConvolutionEffect::setData(const GrGLInterface* gl, - const GrCustomStage* data, - const GrGLTexture* texture) { + const GrGLTexture& texture, + GrCustomStage* data, + int stageNum) { const GrConvolutionEffect* conv = static_cast<const GrConvolutionEffect*>(data); // the code we generated was for a specific kernel width @@ -153,10 +156,10 @@ void GrGLConvolutionEffect::setData(const GrGLInterface* gl, float imageIncrement[2] = { 0 }; switch (conv->direction()) { case GrSamplerState::kX_FilterDirection: - imageIncrement[0] = 1.0f / texture->width(); + imageIncrement[0] = 1.0f / texture.width(); break; case GrSamplerState::kY_FilterDirection: - imageIncrement[1] = 1.0f / texture->width(); + imageIncrement[1] = 1.0f / texture.width(); break; default: GrCrash("Unknown filter direction."); diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp index 755a2f81e8..8fc3ac2b3b 100644 --- a/src/gpu/gl/GrGLProgram.cpp +++ b/src/gpu/gl/GrGLProgram.cpp @@ -1588,11 +1588,9 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, } if (NULL != customStage) { - GrStringBuilder vertexShader; - customStage->emitVS(&vertexShader, varyingVSName); segments->fVSCode.appendf("\t{ // stage %d %s\n", stageNum, customStage->name()); - segments->fVSCode.append(vertexShader); + customStage->emitVS(segments, varyingVSName); segments->fVSCode.appendf("\t}\n"); } @@ -1631,30 +1629,32 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, } segments->fComplexCoord = false; - switch (desc.fCoordMapping) { - case StageDesc::kIdentity_CoordMapping: - // Do nothing - break; - case StageDesc::kSweepGradient_CoordMapping: - segments->fSampleCoords.printf("vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)", segments->fSampleCoords.c_str(), segments->fSampleCoords.c_str()); - segments->fComplexCoord = true; - break; - case StageDesc::kRadialGradient_CoordMapping: - segments->fSampleCoords.printf("vec2(length(%s.xy), 0.5)", segments->fSampleCoords.c_str()); - segments->fComplexCoord = true; - break; - case StageDesc::kRadial2Gradient_CoordMapping: - genRadial2GradientCoordMapping( - stageNum, segments, - radial2VaryingFSName, radial2Params); - break; - case StageDesc::kRadial2GradientDegenerate_CoordMapping: - genRadial2GradientDegenerateCoordMapping( - stageNum, segments, - radial2VaryingFSName, radial2Params); - break; - - }; + // NOTE: GrGLProgramStages will soon responsible for mapping + //if (NULL == customStage) { + switch (desc.fCoordMapping) { + case StageDesc::kIdentity_CoordMapping: + // Do nothing + break; + case StageDesc::kSweepGradient_CoordMapping: + segments->fSampleCoords.printf("vec2(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5, 0.5)", segments->fSampleCoords.c_str(), segments->fSampleCoords.c_str()); + segments->fComplexCoord = true; + break; + case StageDesc::kRadialGradient_CoordMapping: + segments->fSampleCoords.printf("vec2(length(%s.xy), 0.5)", segments->fSampleCoords.c_str()); + segments->fComplexCoord = true; + break; + case StageDesc::kRadial2Gradient_CoordMapping: + genRadial2GradientCoordMapping( + stageNum, segments, + radial2VaryingFSName, radial2Params); + break; + case StageDesc::kRadial2GradientDegenerate_CoordMapping: + genRadial2GradientDegenerateCoordMapping( + stageNum, segments, + radial2VaryingFSName, radial2Params); + break; + } + //} static const uint32_t kMulByAlphaMask = (StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag | @@ -1697,52 +1697,55 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, locations->fTexDomUni = kUseUniform; } - switch (desc.fFetchMode) { - case StageDesc::k2x2_FetchMode: - GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); - gen2x2FS(stageNum, segments, locations, - samplerName, texelSizeName, swizzle, fsOutColor, - texFunc, modulate); - break; - case StageDesc::kConvolution_FetchMode: - GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); - break; - case StageDesc::kDilate_FetchMode: - case StageDesc::kErode_FetchMode: - GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); - genMorphologyFS(stageNum, desc, segments, - samplerName, swizzle, imageIncrementName, fsOutColor, - texFunc, modulate); - break; - default: - if (desc.fInConfigFlags & kMulByAlphaMask) { - // only one of the mul by alpha flags should be set - GrAssert(GrIsPow2(kMulByAlphaMask & desc.fInConfigFlags)); - GrAssert(!(desc.fInConfigFlags & - StageDesc::kSmearAlpha_InConfigFlag)); - GrAssert(!(desc.fInConfigFlags & - StageDesc::kSmearRed_InConfigFlag)); - segments->fFSCode.appendf("\t%s = %s(%s, %s)%s;\n", - fsOutColor, texFunc.c_str(), - samplerName, - segments->fSampleCoords.c_str(), - swizzle); - if (desc.fInConfigFlags & - StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag) { - segments->fFSCode.appendf("\t%s = vec4(ceil(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n", - fsOutColor, fsOutColor, fsOutColor, - fsOutColor, modulate.c_str()); + // NOTE: GrGLProgramStages are now responsible for fetching + if (NULL == customStage) { + switch (desc.fFetchMode) { + case StageDesc::k2x2_FetchMode: + GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); + gen2x2FS(stageNum, segments, locations, + samplerName, texelSizeName, swizzle, fsOutColor, + texFunc, modulate); + break; + case StageDesc::kConvolution_FetchMode: + GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); + break; + case StageDesc::kDilate_FetchMode: + case StageDesc::kErode_FetchMode: + GrAssert(!(desc.fInConfigFlags & kMulByAlphaMask)); + genMorphologyFS(stageNum, desc, segments, + samplerName, swizzle, imageIncrementName, fsOutColor, + texFunc, modulate); + break; + default: + if (desc.fInConfigFlags & kMulByAlphaMask) { + // only one of the mul by alpha flags should be set + GrAssert(GrIsPow2(kMulByAlphaMask & desc.fInConfigFlags)); + GrAssert(!(desc.fInConfigFlags & + StageDesc::kSmearAlpha_InConfigFlag)); + GrAssert(!(desc.fInConfigFlags & + StageDesc::kSmearRed_InConfigFlag)); + segments->fFSCode.appendf("\t%s = %s(%s, %s)%s;\n", + fsOutColor, texFunc.c_str(), + samplerName, + segments->fSampleCoords.c_str(), + swizzle); + if (desc.fInConfigFlags & + StageDesc::kMulRGBByAlpha_RoundUp_InConfigFlag) { + segments->fFSCode.appendf("\t%s = vec4(ceil(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n", + fsOutColor, fsOutColor, fsOutColor, + fsOutColor, modulate.c_str()); + } else { + segments->fFSCode.appendf("\t%s = vec4(floor(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n", + fsOutColor, fsOutColor, fsOutColor, + fsOutColor, modulate.c_str()); + } } else { - segments->fFSCode.appendf("\t%s = vec4(floor(%s.rgb*%s.a*255.0)/255.0,%s.a)%s;\n", - fsOutColor, fsOutColor, fsOutColor, - fsOutColor, modulate.c_str()); + segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n", + fsOutColor, texFunc.c_str(), + samplerName, + segments->fSampleCoords.c_str(), + swizzle, modulate.c_str()); } - } else { - segments->fFSCode.appendf("\t%s = %s(%s, %s)%s%s;\n", - fsOutColor, texFunc.c_str(), - samplerName, - segments->fSampleCoords.c_str(), - swizzle, modulate.c_str()); } } @@ -1762,8 +1765,7 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl, segments->fFSCode.appendf("\t{ // stage %d %s \n", stageNum, customStage->name()); customStage->emitTextureSetup(segments); - customStage->emitFS(&segments->fFSCode, fsOutColor, fsInColor, - samplerName, segments->fSampleCoords.c_str()); + customStage->emitFS(segments, fsOutColor, fsInColor, samplerName); segments->fFSCode.appendf("\t}\n"); } } diff --git a/src/gpu/gl/GrGLProgramStage.cpp b/src/gpu/gl/GrGLProgramStage.cpp index 1221631572..b5e2228cd9 100644 --- a/src/gpu/gl/GrGLProgramStage.cpp +++ b/src/gpu/gl/GrGLProgramStage.cpp @@ -25,12 +25,19 @@ void GrGLProgramStage::setupFSUnis(VarArray* fsUnis, int stage) { } +void GrGLProgramStage::setupVaryings(GrGLShaderBuilder* state, int stage) { + +} + void GrGLProgramStage::initUniforms(const GrGLInterface*, int progID) { } -void GrGLProgramStage::setData(const GrGLInterface*, const GrCustomStage*, - const GrGLTexture*) { +void GrGLProgramStage::setData(const GrGLInterface*, + const GrGLTexture&, + GrCustomStage*, + int stageNum) { + } @@ -74,3 +81,15 @@ void GrGLProgramStage::emitTextureLookup(GrStringBuilder* code, } +void GrGLProgramStage::emitDefaultFetch(GrGLShaderBuilder* state, + const char* fsOutColor, + const char* samplerName, + const char* swizzle, + const char* modulate) { + state->fFSCode.appendf("\t%s = ", fsOutColor); + this->emitTextureLookup(&state->fFSCode, samplerName, + state->fSampleCoords.c_str()); + state->fFSCode.appendf("%s%s;\n", swizzle, modulate); +} + + diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h index f072596045..60ab60dbd8 100644 --- a/src/gpu/gl/GrGLProgramStage.h +++ b/src/gpu/gl/GrGLProgramStage.h @@ -10,6 +10,7 @@ #include "GrAllocator.h" #include "GrCustomStage.h" +#include "GrGLProgram.h" #include "GrGLShaderBuilder.h" #include "GrGLShaderVar.h" #include "GrGLSL.h" @@ -38,8 +39,6 @@ public: kUseUniform = 2000 }; - typedef GrTAllocator<GrGLShaderVar> VarArray; - GrGLProgramStage(const GrProgramStageFactory&); virtual ~GrGLProgramStage(); @@ -56,16 +55,22 @@ public: appending the stage number). */ virtual void setupFSUnis(VarArray* fsUnis, int stage); - /** Given an empty GrStringBuilder and the names of variables; - must write shader code into that GrStringBuilder. + /** Creates any varying variables shared between the shaders; + must guarantee they are unique (typically done by + appending the stage number). */ + virtual void setupVaryings(GrGLShaderBuilder* state, int stage); + + /** Appends vertex code to the appropriate GrStringBuilder + on the state. + The code will be inside an otherwise-empty block. Vertex shader input is a vec2 of coordinates, which may be altered. The code will be inside an otherwise-empty block. */ - virtual void emitVS(GrStringBuilder* code, + virtual void emitVS(GrGLShaderBuilder* state, const char* vertexCoords) = 0; - /** Given an empty GrStringBuilder and the names of variables; - must write shader code into that GrStringBuilder. + /** Appends fragment code to the appropriate GrStringBuilder + on the state. The code will be inside an otherwise-empty block. Fragment shader inputs are a vec2 of coordinates, one texture, and a color; output is a color. */ @@ -73,26 +78,23 @@ public: a function here for them to call into that'll apply any texture domain - but do we force them to be honest about texture domain parameters? */ - virtual void emitFS(GrStringBuilder* code, + virtual void emitFS(GrGLShaderBuilder* state, const char* outputColor, const char* inputColor, - const char* samplerName, - const char* sampleCoords) = 0; + const char* samplerName) = 0; /** Binds uniforms; we must have already bound the program and determined its GL program ID. */ - virtual void initUniforms(const GrGLInterface*, int programID); + virtual void initUniforms(const GrGLInterface* gl, int programID); /** A GrGLCustomStage instance can be reused with any GrCustomStage that produces the same stage key; this function reads data from a stage and uploads any uniform variables required by the shaders - created in emit*(). - flush() to change the GrCustomStage from which the uniforms - are to be read. - TODO: since we don't have a factory, we can't assert to enforce - this. Shouldn't we? */ - virtual void setData(const GrGLInterface*, const GrCustomStage*, - const GrGLTexture*); + created in emit*(). */ + virtual void setData(const GrGLInterface* gl, + const GrGLTexture& texture, + GrCustomStage* stage, + int stageNum); // TODO: needs a better name enum SamplerMode { @@ -121,6 +123,14 @@ protected: const char* samplerName, const char* coordName); + /** Standard texture fetch, complete with swizzle & modulate if + appropriate. */ + void emitDefaultFetch(GrGLShaderBuilder* state, + const char* fsOutColor, + const char* samplerName, + const char* swizzle, + const char* modulate); + SamplerMode fSamplerMode; const GrProgramStageFactory& fFactory; diff --git a/src/gpu/gl/GrGpuGLShaders.cpp b/src/gpu/gl/GrGpuGLShaders.cpp index 0589cfe3c6..802574ceb1 100644 --- a/src/gpu/gl/GrGpuGLShaders.cpp +++ b/src/gpu/gl/GrGpuGLShaders.cpp @@ -764,7 +764,8 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) { static_cast<const GrGLTexture*>( this->getDrawState().getTexture(s)); fProgramData->fCustomStage[s]->setData( - this->glInterface(), sampler.getCustomStage(), texture); + this->glInterface(), *texture, + sampler.getCustomStage(), s); } } } |