gfx/skia/trunk/src/gpu/effects/GrBezierEffect.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/effects/GrBezierEffect.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,443 @@
     1.4 +/*
     1.5 + * Copyright 2013 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#include "GrBezierEffect.h"
    1.12 +
    1.13 +#include "gl/GrGLEffect.h"
    1.14 +#include "gl/GrGLSL.h"
    1.15 +#include "gl/GrGLVertexEffect.h"
    1.16 +#include "GrTBackendEffectFactory.h"
    1.17 +
    1.18 +class GrGLConicEffect : public GrGLVertexEffect {
    1.19 +public:
    1.20 +    GrGLConicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
    1.21 +
    1.22 +    virtual void emitCode(GrGLFullShaderBuilder* builder,
    1.23 +                          const GrDrawEffect& drawEffect,
    1.24 +                          EffectKey key,
    1.25 +                          const char* outputColor,
    1.26 +                          const char* inputColor,
    1.27 +                          const TransformedCoordsArray&,
    1.28 +                          const TextureSamplerArray&) SK_OVERRIDE;
    1.29 +
    1.30 +    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
    1.31 +
    1.32 +    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
    1.33 +
    1.34 +private:
    1.35 +    GrEffectEdgeType fEdgeType;
    1.36 +
    1.37 +    typedef GrGLVertexEffect INHERITED;
    1.38 +};
    1.39 +
    1.40 +GrGLConicEffect::GrGLConicEffect(const GrBackendEffectFactory& factory,
    1.41 +                                 const GrDrawEffect& drawEffect)
    1.42 +    : INHERITED (factory) {
    1.43 +    const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
    1.44 +    fEdgeType = ce.getEdgeType();
    1.45 +}
    1.46 +
    1.47 +void GrGLConicEffect::emitCode(GrGLFullShaderBuilder* builder,
    1.48 +                               const GrDrawEffect& drawEffect,
    1.49 +                               EffectKey key,
    1.50 +                               const char* outputColor,
    1.51 +                               const char* inputColor,
    1.52 +                               const TransformedCoordsArray&,
    1.53 +                               const TextureSamplerArray& samplers) {
    1.54 +    const char *vsName, *fsName;
    1.55 +
    1.56 +    builder->addVarying(kVec4f_GrSLType, "ConicCoeffs",
    1.57 +                              &vsName, &fsName);
    1.58 +    const SkString* attr0Name =
    1.59 +        builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
    1.60 +    builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
    1.61 +
    1.62 +    builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
    1.63 +
    1.64 +    switch (fEdgeType) {
    1.65 +        case kHairlineAA_GrEffectEdgeType: {
    1.66 +            SkAssertResult(builder->enableFeature(
    1.67 +                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
    1.68 +            builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
    1.69 +            builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
    1.70 +            builder->fsCodeAppendf("\t\tfloat dfdx =\n"
    1.71 +                                   "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
    1.72 +                                   fsName, fsName, fsName);
    1.73 +            builder->fsCodeAppendf("\t\tfloat dfdy =\n"
    1.74 +                                   "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
    1.75 +                                   fsName, fsName, fsName);
    1.76 +            builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
    1.77 +            builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
    1.78 +            builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
    1.79 +                                   fsName, fsName);
    1.80 +            builder->fsCodeAppend("\t\tfunc = abs(func);\n");
    1.81 +            builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
    1.82 +            builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
    1.83 +            // Add line below for smooth cubic ramp
    1.84 +            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
    1.85 +            break;
    1.86 +        }
    1.87 +        case kFillAA_GrEffectEdgeType: {
    1.88 +            SkAssertResult(builder->enableFeature(
    1.89 +                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
    1.90 +            builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
    1.91 +            builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
    1.92 +            builder->fsCodeAppendf("\t\tfloat dfdx =\n"
    1.93 +                                   "\t\t\t2.0*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
    1.94 +                                   fsName, fsName, fsName);
    1.95 +            builder->fsCodeAppendf("\t\tfloat dfdy =\n"
    1.96 +                                   "\t\t\t2.0*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
    1.97 +                                   fsName, fsName, fsName);
    1.98 +            builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
    1.99 +            builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
   1.100 +            builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
   1.101 +                                   fsName, fsName);
   1.102 +            builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
   1.103 +            builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
   1.104 +            // Add line below for smooth cubic ramp
   1.105 +            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
   1.106 +            break;
   1.107 +        }
   1.108 +        case kFillBW_GrEffectEdgeType: {
   1.109 +            builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x - %s.y*%s.z;\n", fsName, fsName,
   1.110 +                                   fsName, fsName);
   1.111 +            builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
   1.112 +            break;
   1.113 +        }
   1.114 +        default:
   1.115 +            GrCrash("Shouldn't get here");
   1.116 +    }
   1.117 +
   1.118 +    builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
   1.119 +                           (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
   1.120 +}
   1.121 +
   1.122 +GrGLEffect::EffectKey GrGLConicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
   1.123 +    const GrConicEffect& ce = drawEffect.castEffect<GrConicEffect>();
   1.124 +    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
   1.125 +}
   1.126 +
   1.127 +//////////////////////////////////////////////////////////////////////////////
   1.128 +
   1.129 +GrConicEffect::~GrConicEffect() {}
   1.130 +
   1.131 +const GrBackendEffectFactory& GrConicEffect::getFactory() const {
   1.132 +    return GrTBackendEffectFactory<GrConicEffect>::getInstance();
   1.133 +}
   1.134 +
   1.135 +GrConicEffect::GrConicEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
   1.136 +    this->addVertexAttrib(kVec4f_GrSLType);
   1.137 +    fEdgeType = edgeType;
   1.138 +}
   1.139 +
   1.140 +bool GrConicEffect::onIsEqual(const GrEffect& other) const {
   1.141 +    const GrConicEffect& ce = CastEffect<GrConicEffect>(other);
   1.142 +    return (ce.fEdgeType == fEdgeType);
   1.143 +}
   1.144 +
   1.145 +//////////////////////////////////////////////////////////////////////////////
   1.146 +
   1.147 +GR_DEFINE_EFFECT_TEST(GrConicEffect);
   1.148 +
   1.149 +GrEffectRef* GrConicEffect::TestCreate(SkRandom* random,
   1.150 +                                             GrContext*,
   1.151 +                                             const GrDrawTargetCaps& caps,
   1.152 +                                             GrTexture*[]) {
   1.153 +    GrEffectRef* effect;
   1.154 +    do {
   1.155 +        GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
   1.156 +                                                    random->nextULessThan(kGrEffectEdgeTypeCnt));
   1.157 +        effect = GrConicEffect::Create(edgeType, caps);
   1.158 +    } while (NULL == effect);
   1.159 +    return effect;
   1.160 +}
   1.161 +
   1.162 +//////////////////////////////////////////////////////////////////////////////
   1.163 +// Quad
   1.164 +//////////////////////////////////////////////////////////////////////////////
   1.165 +
   1.166 +class GrGLQuadEffect : public GrGLVertexEffect {
   1.167 +public:
   1.168 +    GrGLQuadEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
   1.169 +
   1.170 +    virtual void emitCode(GrGLFullShaderBuilder* builder,
   1.171 +                          const GrDrawEffect& drawEffect,
   1.172 +                          EffectKey key,
   1.173 +                          const char* outputColor,
   1.174 +                          const char* inputColor,
   1.175 +                          const TransformedCoordsArray&,
   1.176 +                          const TextureSamplerArray&) SK_OVERRIDE;
   1.177 +
   1.178 +    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
   1.179 +
   1.180 +    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
   1.181 +
   1.182 +private:
   1.183 +    GrEffectEdgeType fEdgeType;
   1.184 +
   1.185 +    typedef GrGLVertexEffect INHERITED;
   1.186 +};
   1.187 +
   1.188 +GrGLQuadEffect::GrGLQuadEffect(const GrBackendEffectFactory& factory,
   1.189 +                                 const GrDrawEffect& drawEffect)
   1.190 +    : INHERITED (factory) {
   1.191 +    const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
   1.192 +    fEdgeType = ce.getEdgeType();
   1.193 +}
   1.194 +
   1.195 +void GrGLQuadEffect::emitCode(GrGLFullShaderBuilder* builder,
   1.196 +                              const GrDrawEffect& drawEffect,
   1.197 +                              EffectKey key,
   1.198 +                              const char* outputColor,
   1.199 +                              const char* inputColor,
   1.200 +                              const TransformedCoordsArray&,
   1.201 +                              const TextureSamplerArray& samplers) {
   1.202 +    const char *vsName, *fsName;
   1.203 +
   1.204 +    const SkString* attrName =
   1.205 +        builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
   1.206 +    builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n");
   1.207 +
   1.208 +    builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName);
   1.209 +
   1.210 +    switch (fEdgeType) {
   1.211 +        case kHairlineAA_GrEffectEdgeType: {
   1.212 +            SkAssertResult(builder->enableFeature(
   1.213 +                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
   1.214 +            builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
   1.215 +            builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
   1.216 +            builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
   1.217 +                                   "\t\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
   1.218 +                                   fsName, fsName);
   1.219 +            builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
   1.220 +                                   fsName);
   1.221 +            builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n");
   1.222 +            builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
   1.223 +            // Add line below for smooth cubic ramp
   1.224 +            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
   1.225 +            break;
   1.226 +        }
   1.227 +        case kFillAA_GrEffectEdgeType: {
   1.228 +            SkAssertResult(builder->enableFeature(
   1.229 +                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
   1.230 +            builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName);
   1.231 +            builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName);
   1.232 +            builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n"
   1.233 +                                   "\t\t               2.0*%s.x*duvdy.x - duvdy.y);\n",
   1.234 +                                   fsName, fsName);
   1.235 +            builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
   1.236 +                                   fsName);
   1.237 +            builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha / sqrt(dot(gF, gF));\n");
   1.238 +            builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
   1.239 +            // Add line below for smooth cubic ramp
   1.240 +            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
   1.241 +            break;
   1.242 +        }
   1.243 +        case kFillBW_GrEffectEdgeType: {
   1.244 +            builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName,
   1.245 +                                   fsName);
   1.246 +            builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
   1.247 +            break;
   1.248 +        }
   1.249 +        default:
   1.250 +            GrCrash("Shouldn't get here");
   1.251 +    }
   1.252 +
   1.253 +    builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
   1.254 +                           (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
   1.255 +
   1.256 +
   1.257 +    builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str());
   1.258 +}
   1.259 +
   1.260 +GrGLEffect::EffectKey GrGLQuadEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
   1.261 +    const GrQuadEffect& ce = drawEffect.castEffect<GrQuadEffect>();
   1.262 +    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
   1.263 +}
   1.264 +
   1.265 +//////////////////////////////////////////////////////////////////////////////
   1.266 +
   1.267 +GrQuadEffect::~GrQuadEffect() {}
   1.268 +
   1.269 +const GrBackendEffectFactory& GrQuadEffect::getFactory() const {
   1.270 +    return GrTBackendEffectFactory<GrQuadEffect>::getInstance();
   1.271 +}
   1.272 +
   1.273 +GrQuadEffect::GrQuadEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
   1.274 +    this->addVertexAttrib(kVec4f_GrSLType);
   1.275 +    fEdgeType = edgeType;
   1.276 +}
   1.277 +
   1.278 +bool GrQuadEffect::onIsEqual(const GrEffect& other) const {
   1.279 +    const GrQuadEffect& ce = CastEffect<GrQuadEffect>(other);
   1.280 +    return (ce.fEdgeType == fEdgeType);
   1.281 +}
   1.282 +
   1.283 +//////////////////////////////////////////////////////////////////////////////
   1.284 +
   1.285 +GR_DEFINE_EFFECT_TEST(GrQuadEffect);
   1.286 +
   1.287 +GrEffectRef* GrQuadEffect::TestCreate(SkRandom* random,
   1.288 +                                             GrContext*,
   1.289 +                                             const GrDrawTargetCaps& caps,
   1.290 +                                             GrTexture*[]) {
   1.291 +    GrEffectRef* effect;
   1.292 +    do {
   1.293 +        GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
   1.294 +                                                    random->nextULessThan(kGrEffectEdgeTypeCnt));
   1.295 +        effect = GrQuadEffect::Create(edgeType, caps);
   1.296 +    } while (NULL == effect);
   1.297 +    return effect;
   1.298 +}
   1.299 +
   1.300 +//////////////////////////////////////////////////////////////////////////////
   1.301 +// Cubic
   1.302 +//////////////////////////////////////////////////////////////////////////////
   1.303 +
   1.304 +class GrGLCubicEffect : public GrGLVertexEffect {
   1.305 +public:
   1.306 +    GrGLCubicEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
   1.307 +
   1.308 +    virtual void emitCode(GrGLFullShaderBuilder* builder,
   1.309 +                          const GrDrawEffect& drawEffect,
   1.310 +                          EffectKey key,
   1.311 +                          const char* outputColor,
   1.312 +                          const char* inputColor,
   1.313 +                          const TransformedCoordsArray&,
   1.314 +                          const TextureSamplerArray&) SK_OVERRIDE;
   1.315 +
   1.316 +    static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
   1.317 +
   1.318 +    virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {}
   1.319 +
   1.320 +private:
   1.321 +    GrEffectEdgeType fEdgeType;
   1.322 +
   1.323 +    typedef GrGLVertexEffect INHERITED;
   1.324 +};
   1.325 +
   1.326 +GrGLCubicEffect::GrGLCubicEffect(const GrBackendEffectFactory& factory,
   1.327 +                                 const GrDrawEffect& drawEffect)
   1.328 +    : INHERITED (factory) {
   1.329 +    const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
   1.330 +    fEdgeType = ce.getEdgeType();
   1.331 +}
   1.332 +
   1.333 +void GrGLCubicEffect::emitCode(GrGLFullShaderBuilder* builder,
   1.334 +                               const GrDrawEffect& drawEffect,
   1.335 +                               EffectKey key,
   1.336 +                               const char* outputColor,
   1.337 +                               const char* inputColor,
   1.338 +                               const TransformedCoordsArray&,
   1.339 +                               const TextureSamplerArray& samplers) {
   1.340 +    const char *vsName, *fsName;
   1.341 +
   1.342 +    builder->addVarying(kVec4f_GrSLType, "CubicCoeffs",
   1.343 +                              &vsName, &fsName);
   1.344 +    const SkString* attr0Name =
   1.345 +        builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]);
   1.346 +    builder->vsCodeAppendf("\t%s = %s;\n", vsName, attr0Name->c_str());
   1.347 +
   1.348 +    builder->fsCodeAppend("\t\tfloat edgeAlpha;\n");
   1.349 +
   1.350 +    switch (fEdgeType) {
   1.351 +        case kHairlineAA_GrEffectEdgeType: {
   1.352 +            SkAssertResult(builder->enableFeature(
   1.353 +                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
   1.354 +            builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
   1.355 +            builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
   1.356 +            builder->fsCodeAppendf("\t\tfloat dfdx =\n"
   1.357 +                                   "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
   1.358 +                                   fsName, fsName, fsName, fsName);
   1.359 +            builder->fsCodeAppendf("\t\tfloat dfdy =\n"
   1.360 +                                   "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
   1.361 +                                   fsName, fsName, fsName, fsName);
   1.362 +            builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
   1.363 +            builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
   1.364 +            builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
   1.365 +                                   fsName, fsName, fsName, fsName, fsName);
   1.366 +            builder->fsCodeAppend("\t\tfunc = abs(func);\n");
   1.367 +            builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
   1.368 +            builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n");
   1.369 +            // Add line below for smooth cubic ramp
   1.370 +            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
   1.371 +            break;
   1.372 +        }
   1.373 +        case kFillAA_GrEffectEdgeType: {
   1.374 +            SkAssertResult(builder->enableFeature(
   1.375 +                    GrGLShaderBuilder::kStandardDerivatives_GLSLFeature));
   1.376 +            builder->fsCodeAppendf("\t\tvec3 dklmdx = dFdx(%s.xyz);\n", fsName);
   1.377 +            builder->fsCodeAppendf("\t\tvec3 dklmdy = dFdy(%s.xyz);\n", fsName);
   1.378 +            builder->fsCodeAppendf("\t\tfloat dfdx =\n"
   1.379 +                                   "\t\t3.0*%s.x*%s.x*dklmdx.x - %s.y*dklmdx.z - %s.z*dklmdx.y;\n",
   1.380 +                                   fsName, fsName, fsName, fsName);
   1.381 +            builder->fsCodeAppendf("\t\tfloat dfdy =\n"
   1.382 +                                   "\t\t3.0*%s.x*%s.x*dklmdy.x - %s.y*dklmdy.z - %s.z*dklmdy.y;\n",
   1.383 +                                   fsName, fsName, fsName, fsName);
   1.384 +            builder->fsCodeAppend("\t\tvec2 gF = vec2(dfdx, dfdy);\n");
   1.385 +            builder->fsCodeAppend("\t\tfloat gFM = sqrt(dot(gF, gF));\n");
   1.386 +            builder->fsCodeAppendf("\t\tfloat func = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
   1.387 +                                   fsName, fsName, fsName, fsName, fsName);
   1.388 +            builder->fsCodeAppend("\t\tedgeAlpha = func / gFM;\n");
   1.389 +            builder->fsCodeAppend("\t\tedgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);\n");
   1.390 +            // Add line below for smooth cubic ramp
   1.391 +            // builder->fsCodeAppend("\t\tedgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);\n");
   1.392 +            break;
   1.393 +        }
   1.394 +        case kFillBW_GrEffectEdgeType: {
   1.395 +            builder->fsCodeAppendf("\t\tedgeAlpha = %s.x*%s.x*%s.x - %s.y*%s.z;\n",
   1.396 +                                   fsName, fsName, fsName, fsName, fsName);
   1.397 +            builder->fsCodeAppend("\t\tedgeAlpha = float(edgeAlpha < 0.0);\n");
   1.398 +            break;
   1.399 +        }
   1.400 +        default:
   1.401 +            GrCrash("Shouldn't get here");
   1.402 +    }
   1.403 +
   1.404 +    builder->fsCodeAppendf("\t%s = %s;\n", outputColor,
   1.405 +                           (GrGLSLExpr4(inputColor) * GrGLSLExpr1("edgeAlpha")).c_str());
   1.406 +}
   1.407 +
   1.408 +GrGLEffect::EffectKey GrGLCubicEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
   1.409 +    const GrCubicEffect& ce = drawEffect.castEffect<GrCubicEffect>();
   1.410 +    return ce.isAntiAliased() ? (ce.isFilled() ? 0x0 : 0x1) : 0x2;
   1.411 +}
   1.412 +
   1.413 +//////////////////////////////////////////////////////////////////////////////
   1.414 +
   1.415 +GrCubicEffect::~GrCubicEffect() {}
   1.416 +
   1.417 +const GrBackendEffectFactory& GrCubicEffect::getFactory() const {
   1.418 +    return GrTBackendEffectFactory<GrCubicEffect>::getInstance();
   1.419 +}
   1.420 +
   1.421 +GrCubicEffect::GrCubicEffect(GrEffectEdgeType edgeType) : GrVertexEffect() {
   1.422 +    this->addVertexAttrib(kVec4f_GrSLType);
   1.423 +    fEdgeType = edgeType;
   1.424 +}
   1.425 +
   1.426 +bool GrCubicEffect::onIsEqual(const GrEffect& other) const {
   1.427 +    const GrCubicEffect& ce = CastEffect<GrCubicEffect>(other);
   1.428 +    return (ce.fEdgeType == fEdgeType);
   1.429 +}
   1.430 +
   1.431 +//////////////////////////////////////////////////////////////////////////////
   1.432 +
   1.433 +GR_DEFINE_EFFECT_TEST(GrCubicEffect);
   1.434 +
   1.435 +GrEffectRef* GrCubicEffect::TestCreate(SkRandom* random,
   1.436 +                                             GrContext*,
   1.437 +                                             const GrDrawTargetCaps& caps,
   1.438 +                                             GrTexture*[]) {
   1.439 +    GrEffectRef* effect;
   1.440 +    do {
   1.441 +        GrEffectEdgeType edgeType = static_cast<GrEffectEdgeType>(
   1.442 +                                                    random->nextULessThan(kGrEffectEdgeTypeCnt));
   1.443 +        effect = GrCubicEffect::Create(edgeType, caps);
   1.444 +    } while (NULL == effect);
   1.445 +    return effect;
   1.446 +}

mercurial