aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar tomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-24 15:10:14 +0000
committerGravatar tomhudson@google.com <tomhudson@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-24 15:10:14 +0000
commit6a820b652e2cbd9e1c7ee2885993b0ffd331c040 (patch)
tree6e102d8c489419cff499c2e6dec14db9cc790168
parent8137fcfa7de5132d0358ace615f1e073fe48a7f2 (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
-rw-r--r--src/gpu/effects/GrConvolutionEffect.cpp35
-rw-r--r--src/gpu/gl/GrGLProgram.cpp148
-rw-r--r--src/gpu/gl/GrGLProgramStage.cpp23
-rw-r--r--src/gpu/gl/GrGLProgramStage.h46
-rw-r--r--src/gpu/gl/GrGpuGLShaders.cpp3
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);
}
}
}