aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu
diff options
context:
space:
mode:
authorGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-08-03 14:34:46 +0000
committerGravatar bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-08-03 14:34:46 +0000
commitd472620458e2383e6dd949f4e1aaf61160717ffe (patch)
tree2822ac4f1c55d6eaa9ed4ac6dc2b7014de5410ff /src/gpu
parentdea8e252e1259f5bdd15e16a21646402058b939d (diff)
Registry-based unit test for custom effects
Review URL: http://codereview.appspot.com/6447085/ git-svn-id: http://skia.googlecode.com/svn/trunk@4946 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu')
-rw-r--r--src/gpu/GrCustomStage.cpp7
-rw-r--r--src/gpu/effects/GrColorTableEffect.cpp19
-rw-r--r--src/gpu/gl/GrGLProgram.cpp18
-rw-r--r--src/gpu/gl/GrGLProgram.h6
-rw-r--r--src/gpu/gl/GrGLProgramStage.h7
-rw-r--r--src/gpu/gl/GrGLShaderBuilder.cpp12
6 files changed, 51 insertions, 18 deletions
diff --git a/src/gpu/GrCustomStage.cpp b/src/gpu/GrCustomStage.cpp
index bea07cfab4..6d7bfad272 100644
--- a/src/gpu/GrCustomStage.cpp
+++ b/src/gpu/GrCustomStage.cpp
@@ -13,6 +13,13 @@
SK_DEFINE_INST_COUNT(GrCustomStage)
+#if SK_ALLOW_STATIC_GLOBAL_INITIALIZERS
+SkTArray<GrCustomStageTestFactory*, true>* GrCustomStageTestFactory::GetFactories() {
+ static SkTArray<GrCustomStageTestFactory*, true> gFactories;
+ return &gFactories;
+}
+#endif
+
class GrCustomStage_Globals {
public:
static GrMemoryPool* GetTLS() {
diff --git a/src/gpu/effects/GrColorTableEffect.cpp b/src/gpu/effects/GrColorTableEffect.cpp
index f1ce664826..94eb8fdd74 100644
--- a/src/gpu/effects/GrColorTableEffect.cpp
+++ b/src/gpu/effects/GrColorTableEffect.cpp
@@ -52,11 +52,20 @@ void GrGLColorTableEffect::emitFS(GrGLShaderBuilder* builder,
static const float kColorScaleFactor = 255.0f / 256.0f;
static const float kColorOffsetFactor = 1.0f / 512.0f;
SkString* code = &builder->fFSCode;
- code->appendf("\t\tvec4 coord = vec4(%s.rgb / %s.a, %s.a);\n",
- inputColor, inputColor, inputColor);
- code->appendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
- kColorScaleFactor,
- kColorOffsetFactor, kColorOffsetFactor, kColorOffsetFactor, kColorOffsetFactor);
+ if (NULL == inputColor) {
+ // the input color is solid white (all ones).
+ static const float kMaxValue = kColorScaleFactor + kColorOffsetFactor;
+ code->appendf("\t\tvec4 coord = vec4(%f, %f, %f, %f);\n",
+ kMaxValue, kMaxValue, kMaxValue, kMaxValue);
+
+ } else {
+ code->appendf("\t\tvec4 coord = vec4(%s.rgb / %s.a, %s.a);\n",
+ inputColor, inputColor, inputColor);
+ code->appendf("\t\tcoord = coord * %f + vec4(%f, %f, %f, %f);\n",
+ kColorScaleFactor,
+ kColorOffsetFactor, kColorOffsetFactor,
+ kColorOffsetFactor, kColorOffsetFactor);
+ }
const GrTextureAccess& access = *fCustomStage.textureAccess(0);
code->appendf("\t\t%s.a = ", outputColor);
diff --git a/src/gpu/gl/GrGLProgram.cpp b/src/gpu/gl/GrGLProgram.cpp
index ebbd267fae..b04d924eb5 100644
--- a/src/gpu/gl/GrGLProgram.cpp
+++ b/src/gpu/gl/GrGLProgram.cpp
@@ -301,7 +301,7 @@ static void addColorFilter(SkString* fsCode, const char * outputVar,
add_helper(outputVar, colorStr.c_str(), constStr.c_str(), fsCode);
}
-void GrGLProgram::genEdgeCoverage(SkString* coverageVar,
+bool GrGLProgram::genEdgeCoverage(SkString* coverageVar,
GrGLShaderBuilder* segments) const {
if (fDesc.fVertexLayout & GrDrawTarget::kEdge_VertexLayoutBit) {
const char *vsName, *fsName;
@@ -358,8 +358,10 @@ void GrGLProgram::genEdgeCoverage(SkString* coverageVar,
break;
}
*coverageVar = "edgeAlpha";
+ return true;
} else {
coverageVar->reset();
+ return false;
}
}
@@ -770,7 +772,7 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
if (!wroteFragColorZero || Desc::kNone_DualSrcOutput != fDesc.fDualSrcOutput) {
if (!coverageIsZero) {
- this->genEdgeCoverage(&inCoverage, &builder);
+ bool inCoverageIsScalar = this->genEdgeCoverage(&inCoverage, &builder);
switch (fDesc.fCoverageInput) {
case Desc::kSolidWhite_ColorInput:
@@ -778,9 +780,11 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
break;
case Desc::kAttribute_ColorInput:
gen_attribute_coverage(&builder, &inCoverage);
+ inCoverageIsScalar = false;
break;
case Desc::kUniform_ColorInput:
this->genUniformCoverage(&builder, &inCoverage);
+ inCoverageIsScalar = false;
break;
default:
GrCrash("Unexpected input coverage.");
@@ -793,8 +797,7 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
// create var to hold stage output
outCoverage = "coverage";
outCoverage.appendS32(s);
- builder.fFSCode.appendf("\tvec4 %s;\n",
- outCoverage.c_str());
+ builder.fFSCode.appendf("\tvec4 %s;\n", outCoverage.c_str());
const char* inCoords;
// figure out what our input coords are
@@ -813,6 +816,13 @@ bool GrGLProgram::genProgram(const GrCustomStage** customStages) {
const GrProgramStageFactory& factory = customStages[s]->getFactory();
fProgramStage[s] = factory.createGLInstance(*customStages[s]);
}
+ // stages don't know how to deal with a scalar input. (Maybe they should. We
+ // could pass a GrGLShaderVar)
+ if (inCoverageIsScalar) {
+ builder.fFSCode.appendf("\tvec4 %s4 = vec4(%s);\n",
+ inCoverage.c_str(), inCoverage.c_str());
+ inCoverage.append("4");
+ }
this->genStageCode(s,
inCoverage.size() ? inCoverage.c_str() : NULL,
outCoverage.c_str(),
diff --git a/src/gpu/gl/GrGLProgram.h b/src/gpu/gl/GrGLProgram.h
index 62c70e54bc..989b7c67b4 100644
--- a/src/gpu/gl/GrGLProgram.h
+++ b/src/gpu/gl/GrGLProgram.h
@@ -259,8 +259,10 @@ private:
void genUniformCoverage(GrGLShaderBuilder* segments, SkString* inOutCoverage);
- // generates code to compute coverage based on edge AA.
- void genEdgeCoverage(SkString* coverageVar, GrGLShaderBuilder* builder) const;
+ // generates code to compute coverage based on edge AA. Returns true if edge coverage was
+ // inserted in which case coverageVar will be updated to refer to a scalar. Otherwise,
+ // coverageVar is set to an empty string.
+ bool genEdgeCoverage(SkString* coverageVar, GrGLShaderBuilder* builder) const;
// Creates a GL program ID, binds shader attributes to GL vertex attrs, and links the program
bool bindOutputsAttribsAndLinkProgram(SkString texCoordAttrNames[GrDrawState::kMaxTexCoords],
diff --git a/src/gpu/gl/GrGLProgramStage.h b/src/gpu/gl/GrGLProgramStage.h
index 8e3a4b1584..69095b6f4a 100644
--- a/src/gpu/gl/GrGLProgramStage.h
+++ b/src/gpu/gl/GrGLProgramStage.h
@@ -57,7 +57,12 @@ public:
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. */
+ and a color; output is a color. The input color may be NULL which
+ indicates that the input color is solid white. TODO: Better system
+ for communicating optimization info (e.g. input color is solid white,
+ trans black, known to be opaque, etc.) that allows the custom stage
+ to communicate back similar known info about its output.
+ */
/* TODO: don't give them the samplerName, just a handle; then give
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
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index fb70556709..3ca408618c 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -184,11 +184,7 @@ void GrGLShaderBuilder::emitCustomTextureLookup(SamplerMode samplerMode,
GrCustomStage::StageKey GrGLShaderBuilder::KeyForTextureAccess(const GrTextureAccess& access,
const GrGLCaps& caps) {
GrCustomStage::StageKey key = 0;
-
- if (!access.getTexture()) {
- return key;
- }
-
+
// Assume that swizzle support implies that we never have to modify a shader to adjust
// for texture format/swizzle settings.
if (caps.textureSwizzleSupport()) {
@@ -277,7 +273,11 @@ void GrGLShaderBuilder::addVarying(GrSLType type,
fGSOutputs.push_back();
fGSOutputs.back().setType(type);
fGSOutputs.back().setTypeModifier(GrGLShaderVar::kOut_TypeModifier);
- fGSOutputs.back().accessName()->printf("g%s", name);
+ if (kNonStageIdx == fCurrentStage) {
+ fGSOutputs.back().accessName()->printf("g%s", name);
+ } else {
+ fGSOutputs.back().accessName()->printf("g%s%d", name, fCurrentStage);
+ }
fsName = fGSOutputs.back().accessName();
} else {
fsName = fVSOutputs.back().accessName();