Index: src/effects/gradients/SkTwoPointRadialGradient.cpp |
diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp |
index 53d980aea8a83c49a477dcb818ce41af20ccc18d..e806181630f02121959d96cb040d32296cc00ee6 100644 |
--- a/src/effects/gradients/SkTwoPointRadialGradient.cpp |
+++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp |
@@ -384,6 +384,14 @@ public: |
GrGLRadial2Gradient(const GrBackendEffectFactory& factory, const GrDrawEffect&); |
virtual ~GrGLRadial2Gradient() { } |
+ virtual void emitCode(GrGLFullShaderBuilder*, |
+ const GrDrawEffect&, |
+ EffectKey, |
+ const char* outputColor, |
+ const char* inputColor, |
+ const TransformedCoordsArray&, |
+ const TextureSamplerArray&) SK_OVERRIDE; |
+ |
virtual void emitCode(GrGLShaderBuilder*, |
const GrDrawEffect&, |
EffectKey, |
@@ -391,6 +399,16 @@ public: |
const char* inputColor, |
const TransformedCoordsArray&, |
const TextureSamplerArray&) SK_OVERRIDE; |
+ |
+ void emitUniforms(GrGLShaderBuilder* builder, EffectKey key); |
+ |
+ void emitFragmentCode(GrGLShaderBuilder*, |
+ EffectKey, |
+ const char* outputColor, |
+ const char* inputColor, |
+ const TransformedCoordsArray&, |
+ const TextureSamplerArray&); |
+ |
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; |
static EffectKey GenKey(const GrDrawEffect&, const GrGLCaps& caps); |
@@ -526,15 +544,47 @@ GrGLRadial2Gradient::GrGLRadial2Gradient(const GrBackendEffectFactory& factory, |
fIsDegenerate = data.isDegenerate(); |
} |
-void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder, |
+void GrGLRadial2Gradient::emitCode(GrGLFullShaderBuilder* builder, |
const GrDrawEffect& drawEffect, |
EffectKey key, |
const char* outputColor, |
const char* inputColor, |
const TransformedCoordsArray& coords, |
const TextureSamplerArray& samplers) { |
+ this->emitUniforms(builder, key); |
+ |
+ if (kVec2f_GrSLType == coords[0].type()) { |
+ // For radial gradients without perspective we can pass the linear |
+ // part of the quadratic as a varying. |
+ SkString p2; |
+ SkString p3; |
+ builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); |
+ builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); |
+ |
+ builder->addVarying(kFloat_GrSLType, "Radial2BCoeff", &fVSVaryingName, &fFSVaryingName); |
+ |
+ // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3]) |
+ builder->vsCodeAppendf("\t%s = 2.0 *(%s * %s.x - %s);\n", |
+ fVSVaryingName, p2.c_str(), |
+ coords[0].getVSName().c_str(), p3.c_str()); |
+ } |
+ |
+ this->emitFragmentCode(builder, key, outputColor, inputColor, coords, samplers); |
+} |
+void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder, |
+ const GrDrawEffect&, |
+ EffectKey key, |
+ const char* outputColor, |
+ const char* inputColor, |
+ const TransformedCoordsArray& coords, |
+ const TextureSamplerArray& samplers) { |
this->emitUniforms(builder, key); |
+ this->emitFragmentCode(builder, key, outputColor, inputColor, coords, samplers); |
+} |
+ |
+void GrGLRadial2Gradient::emitUniforms(GrGLShaderBuilder* builder, EffectKey key) { |
+ this->INHERITED::emitUniforms(builder, key); |
// 2 copies of uniform array, 1 for each of vertex & fragment shader, |
// to work around Xoom bug. Doesn't seem to cause performance decrease |
// in test apps, but need to keep an eye on it. |
@@ -542,96 +592,74 @@ void GrGLRadial2Gradient::emitCode(GrGLShaderBuilder* builder, |
kFloat_GrSLType, "Radial2VSParams", 6); |
fFSParamUni = builder->addUniformArray(GrGLShaderBuilder::kFragment_Visibility, |
kFloat_GrSLType, "Radial2FSParams", 6); |
+} |
- // For radial gradients without perspective we can pass the linear |
- // part of the quadratic as a varying. |
- GrGLShaderBuilder::VertexBuilder* vertexBuilder = |
- (kVec2f_GrSLType == coords[0].type()) ? builder->getVertexBuilder() : NULL; |
- if (NULL != vertexBuilder) { |
- vertexBuilder->addVarying(kFloat_GrSLType, "Radial2BCoeff", |
- &fVSVaryingName, &fFSVaryingName); |
+void GrGLRadial2Gradient::emitFragmentCode(GrGLShaderBuilder* builder, |
+ EffectKey key, |
+ const char* outputColor, |
+ const char* inputColor, |
+ const TransformedCoordsArray& coords, |
+ const TextureSamplerArray& samplers) { |
+ SkString coords2D = builder->ensureFSCoords2D(coords, 0); |
+ SkString cName("c"); |
+ SkString ac4Name("ac4"); |
+ SkString rootName("root"); |
+ SkString t; |
+ SkString p0; |
+ SkString p1; |
+ SkString p2; |
+ SkString p3; |
+ SkString p4; |
+ SkString p5; |
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); |
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); |
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); |
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); |
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); |
+ builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); |
+ |
+ // If we we're able to interpolate the linear component, |
+ // bVar is the varying; otherwise compute it |
+ SkString bVar; |
+ if (NULL != fFSVaryingName) { |
+ bVar = fFSVaryingName; |
+ } else { |
+ bVar = "b"; |
+ builder->fsCodeAppendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", |
+ bVar.c_str(), p2.c_str(), coords2D.c_str(), p3.c_str()); |
} |
- // VS |
- { |
- SkString p2; |
- SkString p3; |
- builder->getUniformVariable(fVSParamUni).appendArrayAccess(2, &p2); |
- builder->getUniformVariable(fVSParamUni).appendArrayAccess(3, &p3); |
- |
- // For radial gradients without perspective we can pass the linear |
- // part of the quadratic as a varying. |
- if (NULL != vertexBuilder) { |
- // r2Var = 2 * (r2Parm[2] * varCoord.x - r2Param[3]) |
- vertexBuilder->vsCodeAppendf("\t%s = 2.0 *(%s * %s.x - %s);\n", |
- fVSVaryingName, p2.c_str(), |
- coords[0].getVSName().c_str(), p3.c_str()); |
- } |
+ // c = (x^2)+(y^2) - params[4] |
+ builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", |
+ cName.c_str(), |
+ coords2D.c_str(), |
+ coords2D.c_str(), |
+ p4.c_str()); |
+ |
+ // If we aren't degenerate, emit some extra code, and accept a slightly |
+ // more complex coord. |
+ if (!fIsDegenerate) { |
+ |
+ // ac4 = 4.0 * params[0] * c |
+ builder->fsCodeAppendf("\tfloat %s = %s * 4.0 * %s;\n", |
+ ac4Name.c_str(), p0.c_str(), |
+ cName.c_str()); |
+ |
+ // root = sqrt(b^2-4ac) |
+ // (abs to avoid exception due to fp precision) |
+ builder->fsCodeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n", |
+ rootName.c_str(), bVar.c_str(), bVar.c_str(), |
+ ac4Name.c_str()); |
+ |
+ // t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1] |
+ t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(), |
+ rootName.c_str(), p1.c_str()); |
+ } else { |
+ // t is: -c/b |
+ t.printf("-%s / %s", cName.c_str(), bVar.c_str()); |
} |
- // FS |
- { |
- SkString coords2D = builder->ensureFSCoords2D(coords, 0); |
- SkString cName("c"); |
- SkString ac4Name("ac4"); |
- SkString rootName("root"); |
- SkString t; |
- SkString p0; |
- SkString p1; |
- SkString p2; |
- SkString p3; |
- SkString p4; |
- SkString p5; |
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(0, &p0); |
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(1, &p1); |
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(2, &p2); |
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(3, &p3); |
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(4, &p4); |
- builder->getUniformVariable(fFSParamUni).appendArrayAccess(5, &p5); |
- |
- // If we we're able to interpolate the linear component, |
- // bVar is the varying; otherwise compute it |
- SkString bVar; |
- if (NULL != vertexBuilder) { |
- bVar = fFSVaryingName; |
- } else { |
- bVar = "b"; |
- builder->fsCodeAppendf("\tfloat %s = 2.0 * (%s * %s.x - %s);\n", |
- bVar.c_str(), p2.c_str(), coords2D.c_str(), p3.c_str()); |
- } |
- |
- // c = (x^2)+(y^2) - params[4] |
- builder->fsCodeAppendf("\tfloat %s = dot(%s, %s) - %s;\n", |
- cName.c_str(), |
- coords2D.c_str(), |
- coords2D.c_str(), |
- p4.c_str()); |
- |
- // If we aren't degenerate, emit some extra code, and accept a slightly |
- // more complex coord. |
- if (!fIsDegenerate) { |
- |
- // ac4 = 4.0 * params[0] * c |
- builder->fsCodeAppendf("\tfloat %s = %s * 4.0 * %s;\n", |
- ac4Name.c_str(), p0.c_str(), |
- cName.c_str()); |
- |
- // root = sqrt(b^2-4ac) |
- // (abs to avoid exception due to fp precision) |
- builder->fsCodeAppendf("\tfloat %s = sqrt(abs(%s*%s - %s));\n", |
- rootName.c_str(), bVar.c_str(), bVar.c_str(), |
- ac4Name.c_str()); |
- |
- // t is: (-b + params[5] * sqrt(b^2-4ac)) * params[1] |
- t.printf("(-%s + %s * %s) * %s", bVar.c_str(), p5.c_str(), |
- rootName.c_str(), p1.c_str()); |
- } else { |
- // t is: -c/b |
- t.printf("-%s / %s", cName.c_str(), bVar.c_str()); |
- } |
- |
- this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers); |
- } |
+ this->emitColor(builder, t.c_str(), key, outputColor, inputColor, samplers); |
} |
void GrGLRadial2Gradient::setData(const GrGLUniformManager& uman, |