diff options
-rw-r--r-- | gyp/gpu.gypi | 6 | ||||
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 124 | ||||
-rw-r--r-- | src/gpu/GrAAHairLinePathRenderer.cpp | 210 | ||||
-rw-r--r-- | src/gpu/GrOvalRenderer.cpp | 257 | ||||
-rw-r--r-- | src/gpu/effects/GrCircleEdgeEffect.cpp | 81 | ||||
-rw-r--r-- | src/gpu/effects/GrCircleEdgeEffect.h | 66 | ||||
-rw-r--r-- | src/gpu/effects/GrEdgeEffect.cpp | 132 | ||||
-rw-r--r-- | src/gpu/effects/GrEdgeEffect.h | 85 | ||||
-rw-r--r-- | src/gpu/effects/GrEllipseEdgeEffect.cpp | 102 | ||||
-rw-r--r-- | src/gpu/effects/GrEllipseEdgeEffect.h | 65 |
10 files changed, 582 insertions, 546 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 5887d93c22..259bd01bc9 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -125,16 +125,10 @@ '<(skia_src_path)/gpu/gr_unittests.cpp', '<(skia_src_path)/gpu/effects/Gr1DKernelEffect.h', - '<(skia_src_path)/gpu/effects/GrCircleEdgeEffect.cpp', - '<(skia_src_path)/gpu/effects/GrCircleEdgeEffect.h', '<(skia_src_path)/gpu/effects/GrConfigConversionEffect.cpp', '<(skia_src_path)/gpu/effects/GrConfigConversionEffect.h', '<(skia_src_path)/gpu/effects/GrConvolutionEffect.cpp', '<(skia_src_path)/gpu/effects/GrConvolutionEffect.h', - '<(skia_src_path)/gpu/effects/GrEdgeEffect.cpp', - '<(skia_src_path)/gpu/effects/GrEdgeEffect.h', - '<(skia_src_path)/gpu/effects/GrEllipseEdgeEffect.cpp', - '<(skia_src_path)/gpu/effects/GrEllipseEdgeEffect.h', '<(skia_src_path)/gpu/effects/GrSimpleTextureEffect.cpp', '<(skia_src_path)/gpu/effects/GrSimpleTextureEffect.h', '<(skia_src_path)/gpu/effects/GrSingleTextureEffect.cpp', diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index 53c237b522..ca5addcec9 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -11,12 +11,15 @@ #include "GrContext.h" #include "GrDrawState.h" #include "GrDrawTargetCaps.h" +#include "GrEffect.h" #include "GrPathUtils.h" +#include "GrTBackendEffectFactory.h" #include "SkString.h" #include "SkStrokeRec.h" #include "SkTrace.h" -#include "effects/GrEdgeEffect.h" +#include "gl/GrGLEffect.h" +#include "gl/GrGLSL.h" GrAAConvexPathRenderer::GrAAConvexPathRenderer() { } @@ -431,6 +434,123 @@ void create_vertices(const SegmentArray& segments, } +/////////////////////////////////////////////////////////////////////////////// + +/* + * Quadratic specified by 0=u^2-v canonical coords. u and v are the first + * two components of the vertex attribute. Coverage is based on signed + * distance with negative being inside, positive outside. The edge is specified in + * window space (y-down). If either the third or fourth component of the interpolated + * vertex coord is > 0 then the pixel is considered outside the edge. This is used to + * attempt to trim to a portion of the infinite quad. + * Requires shader derivative instruction support. + */ + +class QuadEdgeEffect : public GrEffect { +public: + + static GrEffectRef* Create() { + // we go through this so we only have one copy of each effect + static GrEffectRef* gQuadEdgeEffectRef = + CreateEffectRef(AutoEffectUnref(SkNEW(QuadEdgeEffect))); + static SkAutoTUnref<GrEffectRef> gUnref(gQuadEdgeEffectRef); + + gQuadEdgeEffectRef->ref(); + return gQuadEdgeEffectRef; + } + + virtual ~QuadEdgeEffect() {} + + static const char* Name() { return "QuadEdge"; } + + virtual void getConstantColorComponents(GrColor* color, + uint32_t* validFlags) const SK_OVERRIDE { + *validFlags = 0; + } + + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { + return GrTBackendEffectFactory<QuadEdgeEffect>::getInstance(); + } + + class GLEffect : public GrGLEffect { + public: + GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) + : INHERITED (factory) {} + + virtual void emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TextureSamplerArray& samplers) SK_OVERRIDE { + const char *vsName, *fsName; + const SkString* attrName = + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); + + SkAssertResult(builder->enableFeature( + GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); + builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName); + + // keep the derivative instructions outside the conditional + builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); + builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); + builder->fsCodeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName); + // today we know z and w are in device space. We could use derivatives + builder->fsCodeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, + fsName); + builder->fsCodeAppendf ("\t\t} else {\n"); + builder->fsCodeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" + "\t\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", + fsName, fsName); + builder->fsCodeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, + fsName); + builder->fsCodeAppendf("\t\t\tedgeAlpha = " + "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n"); + + SkString modulate; + GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); + builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); + + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); + } + + static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { + return 0x0; + } + + virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} + + private: + typedef GrGLEffect INHERITED; + }; + +private: + QuadEdgeEffect() { + this->addVertexAttrib(kVec4f_GrSLType); + } + + virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { + return true; + } + + GR_DECLARE_EFFECT_TEST; + + typedef GrEffect INHERITED; +}; + +GR_DEFINE_EFFECT_TEST(QuadEdgeEffect); + +GrEffectRef* QuadEdgeEffect::TestCreate(SkMWCRandom* random, + GrContext*, + const GrDrawTargetCaps& caps, + GrTexture*[]) { + // Doesn't work without derivative instructions. + return caps.shaderDerivativeSupport() ? QuadEdgeEffect::Create() : NULL; +} + +/////////////////////////////////////////////////////////////////////////////// + bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path, const SkStrokeRec& stroke, const GrDrawTarget* target, @@ -497,7 +617,7 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath, kEdgeEffectStage = GrPaint::kTotalStages, }; static const int kEdgeAttrIndex = 1; - GrEffectRef* quadEffect = GrEdgeEffect::Create(GrEdgeEffect::kQuad_EdgeType); + GrEffectRef* quadEffect = QuadEdgeEffect::Create(); drawState->setEffect(kEdgeEffectStage, quadEffect, kEdgeAttrIndex)->unref(); GrDrawTarget::AutoReleaseGeometry arg(target, vCount, iCount); diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index ffc9c50b2a..fdb6009857 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -11,14 +11,17 @@ #include "GrContext.h" #include "GrDrawState.h" #include "GrDrawTargetCaps.h" +#include "GrEffect.h" #include "GrGpu.h" #include "GrIndexBuffer.h" #include "GrPathUtils.h" +#include "GrTBackendEffectFactory.h" #include "SkGeometry.h" #include "SkStroke.h" #include "SkTemplates.h" -#include "effects/GrEdgeEffect.h" +#include "gl/GrGLEffect.h" +#include "gl/GrGLSL.h" namespace { // quadratics are rendered as 5-sided polys in order to bound the @@ -492,6 +495,207 @@ void add_line(const SkPoint p[2], } +/////////////////////////////////////////////////////////////////////////////// + +/** + * The output of this effect is a hairline edge for quadratics. + * Quadratic specified by 0=u^2-v canonical coords. u and v are the first + * two components of the vertex attribute. Uses unsigned distance. + * Coverage is min(0, 1-distance). 3rd & 4th component unused. + * Requires shader derivative instruction support. + */ +class HairQuadEdgeEffect : public GrEffect { +public: + + static GrEffectRef* Create() { + // we go through this so we only have one copy of each effect + static GrEffectRef* gHairQuadEdgeEffectRef = + CreateEffectRef(AutoEffectUnref(SkNEW(HairQuadEdgeEffect))); + static SkAutoTUnref<GrEffectRef> gUnref(gHairQuadEdgeEffectRef); + + gHairQuadEdgeEffectRef->ref(); + return gHairQuadEdgeEffectRef; + } + + virtual ~HairQuadEdgeEffect() {} + + static const char* Name() { return "HairQuadEdge"; } + + virtual void getConstantColorComponents(GrColor* color, + uint32_t* validFlags) const SK_OVERRIDE { + *validFlags = 0; + } + + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { + return GrTBackendEffectFactory<HairQuadEdgeEffect>::getInstance(); + } + + class GLEffect : public GrGLEffect { + public: + GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) + : INHERITED (factory) {} + + virtual void emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TextureSamplerArray& samplers) SK_OVERRIDE { + const char *vsName, *fsName; + const SkString* attrName = + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); + + SkAssertResult(builder->enableFeature( + GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); + builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName); + + builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); + builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); + builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" + "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", + fsName, fsName); + builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, + fsName); + builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n"); + builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); + + SkString modulate; + GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); + builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); + + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); + } + + static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { + return 0x0; + } + + virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} + + private: + typedef GrGLEffect INHERITED; + }; + +private: + HairQuadEdgeEffect() { + this->addVertexAttrib(kVec4f_GrSLType); + } + + virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { + return true; + } + + GR_DECLARE_EFFECT_TEST; + + typedef GrEffect INHERITED; +}; + +GR_DEFINE_EFFECT_TEST(HairQuadEdgeEffect); + +GrEffectRef* HairQuadEdgeEffect::TestCreate(SkMWCRandom* random, + GrContext*, + const GrDrawTargetCaps& caps, + GrTexture*[]) { + // Doesn't work without derivative instructions. + return caps.shaderDerivativeSupport() ? HairQuadEdgeEffect::Create() : NULL;} + +/////////////////////////////////////////////////////////////////////////////// + +/** + * The output of this effect is a 1-pixel wide line. + * Input is 2D implicit device coord line eq (a*x + b*y +c = 0). 4th component unused. + */ +class HairLineEdgeEffect : public GrEffect { +public: + + static GrEffectRef* Create() { + // we go through this so we only have one copy of each effect + static GrEffectRef* gHairLineEdgeEffectRef = + CreateEffectRef(AutoEffectUnref(SkNEW(HairLineEdgeEffect))); + static SkAutoTUnref<GrEffectRef> gUnref(gHairLineEdgeEffectRef); + + gHairLineEdgeEffectRef->ref(); + return gHairLineEdgeEffectRef; + } + + virtual ~HairLineEdgeEffect() {} + + static const char* Name() { return "HairLineEdge"; } + + virtual void getConstantColorComponents(GrColor* color, + uint32_t* validFlags) const SK_OVERRIDE { + *validFlags = 0; + } + + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { + return GrTBackendEffectFactory<HairLineEdgeEffect>::getInstance(); + } + + class GLEffect : public GrGLEffect { + public: + GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) + : INHERITED (factory) {} + + virtual void emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TextureSamplerArray& samplers) SK_OVERRIDE { + const char *vsName, *fsName; + const SkString* attrName = + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); + + builder->addVarying(kVec4f_GrSLType, "HairLineEdge", &vsName, &fsName); + + builder->fsCodeAppendf("\t\tedgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", + builder->fragmentPosition(), fsName); + builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); + + SkString modulate; + GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); + builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); + + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); + } + + static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { + return 0x0; + } + + virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} + + private: + typedef GrGLEffect INHERITED; + }; + +private: + HairLineEdgeEffect() { + this->addVertexAttrib(kVec4f_GrSLType); + } + + virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { + return true; + } + + GR_DECLARE_EFFECT_TEST; + + typedef GrEffect INHERITED; +}; + +GR_DEFINE_EFFECT_TEST(HairLineEdgeEffect); + +GrEffectRef* HairLineEdgeEffect::TestCreate(SkMWCRandom* random, + GrContext*, + const GrDrawTargetCaps& caps, + GrTexture*[]) { + return HairLineEdgeEffect::Create(); +} + +/////////////////////////////////////////////////////////////////////////////// + bool GrAAHairLinePathRenderer::createGeom( const SkPath& path, GrDrawTarget* target, @@ -611,8 +815,8 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path, }; static const int kEdgeAttrIndex = 1; - GrEffectRef* hairLineEffect = GrEdgeEffect::Create(GrEdgeEffect::kHairLine_EdgeType); - GrEffectRef* hairQuadEffect = GrEdgeEffect::Create(GrEdgeEffect::kHairQuad_EdgeType); + GrEffectRef* hairLineEffect = HairLineEdgeEffect::Create(); + GrEffectRef* hairQuadEffect = HairQuadEdgeEffect::Create(); target->setIndexSourceToBuffer(fLinesIndexBuffer); int lines = 0; diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 2955c75641..65715f8a5b 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -7,8 +7,10 @@ #include "GrOvalRenderer.h" -#include "effects/GrCircleEdgeEffect.h" -#include "effects/GrEllipseEdgeEffect.h" +#include "GrEffect.h" +#include "gl/GrGLEffect.h" +#include "gl/GrGLSL.h" +#include "GrTBackendEffectFactory.h" #include "GrDrawState.h" #include "GrDrawTarget.h" @@ -40,6 +42,253 @@ inline bool circle_stays_circle(const SkMatrix& m) { } +/////////////////////////////////////////////////////////////////////////////// + +/** + * The output of this effect is a modulation of the input color and coverage for a circle, + * specified as center_x, center_y, x_radius, inner radius and outer radius in window space + * (y-down). + */ + +class CircleEdgeEffect : public GrEffect { +public: + static GrEffectRef* Create(bool stroke) { + // we go through this so we only have one copy of each effect (stroked/filled) + static SkAutoTUnref<GrEffectRef> gCircleStrokeEdgeEffectRef( + CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEffect, (true))))); + static SkAutoTUnref<GrEffectRef> gCircleFillEdgeEffectRef( + CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(CircleEdgeEffect, (false))))); + + if (stroke) { + gCircleStrokeEdgeEffectRef.get()->ref(); + return gCircleStrokeEdgeEffectRef; + } else { + gCircleFillEdgeEffectRef.get()->ref(); + return gCircleFillEdgeEffectRef; + } + } + + virtual void getConstantColorComponents(GrColor* color, + uint32_t* validFlags) const SK_OVERRIDE { + *validFlags = 0; + } + + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { + return GrTBackendEffectFactory<CircleEdgeEffect>::getInstance(); + } + + virtual ~CircleEdgeEffect() {} + + static const char* Name() { return "CircleEdge"; } + + inline bool isStroked() const { return fStroke; } + + class GLEffect : public GrGLEffect { + public: + GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) + : INHERITED (factory) {} + + virtual void emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TextureSamplerArray& samplers) SK_OVERRIDE { + const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleEdgeEffect>(); + const char *vsName, *fsName; + builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName); + + const SkString* attrName = + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); + + builder->fsCodeAppendf("\tfloat d = distance(%s.xy, %s.xy);\n", + builder->fragmentPosition(), fsName); + builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName); + if (circleEffect.isStroked()) { + builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName); + builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n"); + } + SkString modulate; + GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); + builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); + } + + static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { + const CircleEdgeEffect& circleEffect = drawEffect.castEffect<CircleEdgeEffect>(); + + return circleEffect.isStroked() ? 0x1 : 0x0; + } + + virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE {} + + private: + typedef GrGLEffect INHERITED; + }; + + +private: + CircleEdgeEffect(bool stroke) : GrEffect() { + this->addVertexAttrib(kVec4f_GrSLType); + fStroke = stroke; + } + + virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { + const CircleEdgeEffect& cee = CastEffect<CircleEdgeEffect>(other); + return cee.fStroke == fStroke; + } + + bool fStroke; + + GR_DECLARE_EFFECT_TEST; + + typedef GrEffect INHERITED; +}; + +GR_DEFINE_EFFECT_TEST(CircleEdgeEffect); + +GrEffectRef* CircleEdgeEffect::TestCreate(SkMWCRandom* random, + GrContext* context, + const GrDrawTargetCaps&, + GrTexture* textures[]) { + return CircleEdgeEffect::Create(random->nextBool()); +} + +/////////////////////////////////////////////////////////////////////////////// + +/** + * The output of this effect is a modulation of the input color and coverage for an axis-aligned + * ellipse, specified as center_x, center_y, x_radius, x_radius/y_radius in window space (y-down). + */ + +class EllipseEdgeEffect : public GrEffect { +public: + static GrEffectRef* Create(bool stroke) { + // we go through this so we only have one copy of each effect (stroked/filled) + static SkAutoTUnref<GrEffectRef> gEllipseStrokeEdgeEffectRef( + CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEffect, (true))))); + static SkAutoTUnref<GrEffectRef> gEllipseFillEdgeEffectRef( + CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(EllipseEdgeEffect, (false))))); + + if (stroke) { + gEllipseStrokeEdgeEffectRef.get()->ref(); + return gEllipseStrokeEdgeEffectRef; + } else { + gEllipseFillEdgeEffectRef.get()->ref(); + return gEllipseFillEdgeEffectRef; + } + } + + virtual void getConstantColorComponents(GrColor* color, + uint32_t* validFlags) const SK_OVERRIDE { + *validFlags = 0; + } + + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { + return GrTBackendEffectFactory<EllipseEdgeEffect>::getInstance(); + } + + virtual ~EllipseEdgeEffect() {} + + static const char* Name() { return "EllipseEdge"; } + + inline bool isStroked() const { return fStroke; } + + class GLEffect : public GrGLEffect { + public: + GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) + : INHERITED (factory) {} + + virtual void emitCode(GrGLShaderBuilder* builder, + const GrDrawEffect& drawEffect, + EffectKey key, + const char* outputColor, + const char* inputColor, + const TextureSamplerArray& samplers) SK_OVERRIDE { + const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<EllipseEdgeEffect>(); + + const char *vsCenterName, *fsCenterName; + const char *vsEdgeName, *fsEdgeName; + + builder->addVarying(kVec2f_GrSLType, "EllipseCenter", &vsCenterName, &fsCenterName); + const SkString* attr0Name = + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); + builder->vsCodeAppendf("\t%s = %s;\n", vsCenterName, attr0Name->c_str()); + + builder->addVarying(kVec4f_GrSLType, "EllipseEdge", &vsEdgeName, &fsEdgeName); + const SkString* attr1Name = + builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); + builder->vsCodeAppendf("\t%s = %s;\n", vsEdgeName, attr1Name->c_str()); + + // translate to origin + builder->fsCodeAppendf("\tvec2 outerOffset = (%s.xy - %s.xy);\n", + builder->fragmentPosition(), fsCenterName); + builder->fsCodeAppend("\tvec2 innerOffset = outerOffset;\n"); + // scale y by xRadius/yRadius + builder->fsCodeAppendf("\touterOffset.y *= %s.y;\n", fsEdgeName); + builder->fsCodeAppend("\tfloat dOuter = length(outerOffset);\n"); + // compare outer lengths against xOuterRadius + builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n", + fsEdgeName); + + if (ellipseEffect.isStroked()) { + builder->fsCodeAppendf("\tinnerOffset.y *= %s.w;\n", fsEdgeName); + builder->fsCodeAppend("\tfloat dInner = length(innerOffset);\n"); + + // compare inner lengths against xInnerRadius + builder->fsCodeAppendf("\tfloat innerAlpha = clamp(dInner-%s.z, 0.0, 1.0);\n", + fsEdgeName); + builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n"); + } + + SkString modulate; + GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); + builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); + } + + static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { + const EllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<EllipseEdgeEffect>(); + + return ellipseEffect.isStroked() ? 0x1 : 0x0; + } + + virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE { + } + + private: + typedef GrGLEffect INHERITED; + }; + +private: + EllipseEdgeEffect(bool stroke) : GrEffect() { + this->addVertexAttrib(kVec2f_GrSLType); + this->addVertexAttrib(kVec4f_GrSLType); + fStroke = stroke; + } + + virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { + const EllipseEdgeEffect& eee = CastEffect<EllipseEdgeEffect>(other); + return eee.fStroke == fStroke; + } + + bool fStroke; + + GR_DECLARE_EFFECT_TEST; + + typedef GrEffect INHERITED; +}; + +GR_DEFINE_EFFECT_TEST(EllipseEdgeEffect); + +GrEffectRef* EllipseEdgeEffect::TestCreate(SkMWCRandom* random, + GrContext* context, + const GrDrawTargetCaps&, + GrTexture* textures[]) { + return EllipseEdgeEffect::Create(random->nextBool()); +} + +/////////////////////////////////////////////////////////////////////////////// + bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, const GrPaint& paint, const GrRect& oval, const SkStrokeRec& stroke) { @@ -108,7 +357,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target, kEdgeEffectStage = GrPaint::kTotalStages, }; - GrEffectRef* effect = GrCircleEdgeEffect::Create(isStroked); + GrEffectRef* effect = CircleEdgeEffect::Create(isStroked); static const int kCircleEdgeAttrIndex = 1; drawState->setEffect(kEdgeEffectStage, effect, kCircleEdgeAttrIndex)->unref(); @@ -207,7 +456,7 @@ void GrOvalRenderer::drawEllipse(GrDrawTarget* target, kEdgeEffectStage = GrPaint::kTotalStages, }; - GrEffectRef* effect = GrEllipseEdgeEffect::Create(isStroked); + GrEffectRef* effect = EllipseEdgeEffect::Create(isStroked); static const int kEllipseCenterAttrIndex = 1; static const int kEllipseEdgeAttrIndex = 2; drawState->setEffect(kEdgeEffectStage, effect, diff --git a/src/gpu/effects/GrCircleEdgeEffect.cpp b/src/gpu/effects/GrCircleEdgeEffect.cpp deleted file mode 100644 index 19544d7179..0000000000 --- a/src/gpu/effects/GrCircleEdgeEffect.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrCircleEdgeEffect.h" -#include "gl/GrGLEffect.h" -#include "gl/GrGLSL.h" -#include "GrTBackendEffectFactory.h" - -class GrGLCircleEdgeEffect : public GrGLEffect { -public: - GrGLCircleEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) - : INHERITED (factory) {} - - virtual void emitCode(GrGLShaderBuilder* builder, - const GrDrawEffect& drawEffect, - EffectKey key, - const char* outputColor, - const char* inputColor, - const TextureSamplerArray& samplers) SK_OVERRIDE { - const GrCircleEdgeEffect& circleEffect = drawEffect.castEffect<GrCircleEdgeEffect>(); - const char *vsName, *fsName; - builder->addVarying(kVec4f_GrSLType, "CircleEdge", &vsName, &fsName); - - const SkString* attrName = - builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); - - builder->fsCodeAppendf("\tfloat d = distance(%s.xy, %s.xy);\n", - builder->fragmentPosition(), fsName); - builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.z - d, 0.0, 1.0);\n", fsName); - if (circleEffect.isStroked()) { - builder->fsCodeAppendf("\tfloat innerAlpha = clamp(d - %s.w, 0.0, 1.0);\n", fsName); - builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n"); - } - SkString modulate; - GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); - builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); - } - - static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { - const GrCircleEdgeEffect& circleEffect = drawEffect.castEffect<GrCircleEdgeEffect>(); - - return circleEffect.isStroked() ? 0x1 : 0x0; - } - - virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE { - } - -private: - typedef GrGLEffect INHERITED; -}; - -/////////////////////////////////////////////////////////////////////////////// - -GrCircleEdgeEffect::GrCircleEdgeEffect(bool stroke) : GrEffect() { - this->addVertexAttrib(kVec4f_GrSLType); - fStroke = stroke; -} - -void GrCircleEdgeEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; -} - -const GrBackendEffectFactory& GrCircleEdgeEffect::getFactory() const { - return GrTBackendEffectFactory<GrCircleEdgeEffect>::getInstance(); -} - -/////////////////////////////////////////////////////////////////////////////// - -GR_DEFINE_EFFECT_TEST(GrCircleEdgeEffect); - -GrEffectRef* GrCircleEdgeEffect::TestCreate(SkMWCRandom* random, - GrContext* context, - const GrDrawTargetCaps&, - GrTexture* textures[]) { - return GrCircleEdgeEffect::Create(random->nextBool()); -} diff --git a/src/gpu/effects/GrCircleEdgeEffect.h b/src/gpu/effects/GrCircleEdgeEffect.h deleted file mode 100644 index 798833353a..0000000000 --- a/src/gpu/effects/GrCircleEdgeEffect.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrCircleEdgeEffect_DEFINED -#define GrCircleEdgeEffect_DEFINED - -#include "GrEffect.h" - -class GrGLCircleEdgeEffect; - -/** - * The output of this effect is a modulation of the input color and coverage for a circle, - * specified as center_x, center_y, x_radius, inner radius and outer radius in window space - * (y-down). - */ - -class GrCircleEdgeEffect : public GrEffect { -public: - static GrEffectRef* Create(bool stroke) { - // we go through this so we only have one copy of each effect (stroked/filled) - static SkAutoTUnref<GrEffectRef> gCircleStrokeEdgeEffectRef( - CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrCircleEdgeEffect, (true))))); - static SkAutoTUnref<GrEffectRef> gCircleFillEdgeEffectRef( - CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrCircleEdgeEffect, (false))))); - - if (stroke) { - gCircleStrokeEdgeEffectRef.get()->ref(); - return gCircleStrokeEdgeEffectRef; - } else { - gCircleFillEdgeEffectRef.get()->ref(); - return gCircleFillEdgeEffectRef; - } - } - - virtual ~GrCircleEdgeEffect() {} - - static const char* Name() { return "CircleEdge"; } - - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - - typedef GrGLCircleEdgeEffect GLEffect; - - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; - - inline bool isStroked() const { return fStroke; } - -private: - GrCircleEdgeEffect(bool stroke); - - virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { - const GrCircleEdgeEffect& cee = CastEffect<GrCircleEdgeEffect>(other); - return cee.fStroke == fStroke; - } - - bool fStroke; - - GR_DECLARE_EFFECT_TEST; - - typedef GrEffect INHERITED; -}; - -#endif diff --git a/src/gpu/effects/GrEdgeEffect.cpp b/src/gpu/effects/GrEdgeEffect.cpp deleted file mode 100644 index 6f56413963..0000000000 --- a/src/gpu/effects/GrEdgeEffect.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrEdgeEffect.h" -#include "gl/GrGLEffect.h" -#include "gl/GrGLSL.h" -#include "GrTBackendEffectFactory.h" - -class GrGLEdgeEffect : public GrGLEffect { -public: - GrGLEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) - : INHERITED (factory) {} - - virtual void emitCode(GrGLShaderBuilder* builder, - const GrDrawEffect& drawEffect, - EffectKey key, - const char* outputColor, - const char* inputColor, - const TextureSamplerArray& samplers) SK_OVERRIDE { - const GrEdgeEffect& edgeEffect = drawEffect.castEffect<GrEdgeEffect>(); - GrEdgeEffect::EdgeType type = edgeEffect.edgeType(); - - const char *vsName, *fsName; - const SkString* attrName = - builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - builder->fsCodeAppendf("\t\tfloat edgeAlpha;\n"); - - switch (type) { - case GrEdgeEffect::kHairLine_EdgeType: - builder->addVarying(kVec4f_GrSLType, "HairEdge", &vsName, &fsName); - - builder->fsCodeAppendf("\t\tedgeAlpha = abs(dot(vec3(%s.xy,1), %s.xyz));\n", - builder->fragmentPosition(), fsName); - builder->fsCodeAppendf("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); - break; - case GrEdgeEffect::kQuad_EdgeType: - SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); - builder->addVarying(kVec4f_GrSLType, "QuadEdge", &vsName, &fsName); - - // keep the derivative instructions outside the conditional - builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); - builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); - builder->fsCodeAppendf("\t\tif (%s.z > 0.0 && %s.w > 0.0) {\n", fsName, fsName); - // today we know z and w are in device space. We could use derivatives - builder->fsCodeAppendf("\t\t\tedgeAlpha = min(min(%s.z, %s.w) + 0.5, 1.0);\n", fsName, - fsName); - builder->fsCodeAppendf ("\t\t} else {\n"); - builder->fsCodeAppendf("\t\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" - "\t\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", - fsName, fsName); - builder->fsCodeAppendf("\t\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, - fsName); - builder->fsCodeAppendf("\t\t\tedgeAlpha = " - "clamp(0.5 - edgeAlpha / length(gF), 0.0, 1.0);\n\t\t}\n"); - break; - case GrEdgeEffect::kHairQuad_EdgeType: - SkAssertResult(builder->enableFeature(GrGLShaderBuilder::kStandardDerivatives_GLSLFeature)); - builder->addVarying(kVec4f_GrSLType, "HairQuadEdge", &vsName, &fsName); - - builder->fsCodeAppendf("\t\tvec2 duvdx = dFdx(%s.xy);\n", fsName); - builder->fsCodeAppendf("\t\tvec2 duvdy = dFdy(%s.xy);\n", fsName); - builder->fsCodeAppendf("\t\tvec2 gF = vec2(2.0*%s.x*duvdx.x - duvdx.y,\n" - "\t\t 2.0*%s.x*duvdy.x - duvdy.y);\n", - fsName, fsName); - builder->fsCodeAppendf("\t\tedgeAlpha = (%s.x*%s.x - %s.y);\n", fsName, fsName, - fsName); - builder->fsCodeAppend("\t\tedgeAlpha = sqrt(edgeAlpha*edgeAlpha / dot(gF, gF));\n"); - builder->fsCodeAppend("\t\tedgeAlpha = max(1.0 - edgeAlpha, 0.0);\n"); - break; - }; - - SkString modulate; - GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); - builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); - - builder->vsCodeAppendf("\t%s = %s;\n", vsName, attrName->c_str()); - } - - static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { - const GrEdgeEffect& QuadEffect = drawEffect.castEffect<GrEdgeEffect>(); - - return QuadEffect.edgeType(); - } - - virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE { - } - -private: - typedef GrGLEffect INHERITED; -}; - -/////////////////////////////////////////////////////////////////////////////// - -GrEdgeEffect::GrEdgeEffect(EdgeType edgeType) : GrEffect() { - if (edgeType == kQuad_EdgeType) { - this->addVertexAttrib(kVec4f_GrSLType); - } else { - this->addVertexAttrib(kVec4f_GrSLType); // TODO: use different vec sizes for differnt edge - // types. - } - fEdgeType = edgeType; -} - -void GrEdgeEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; -} - -const GrBackendEffectFactory& GrEdgeEffect::getFactory() const { - return GrTBackendEffectFactory<GrEdgeEffect>::getInstance(); -} - -/////////////////////////////////////////////////////////////////////////////// - -GR_DEFINE_EFFECT_TEST(GrEdgeEffect); - -GrEffectRef* GrEdgeEffect::TestCreate(SkMWCRandom* random, - GrContext*, - const GrDrawTargetCaps& caps, - GrTexture*[]) { - // Only kHairLine works without derivative instructions. - EdgeType edgeType; - if (caps.shaderDerivativeSupport()) { - edgeType = static_cast<EdgeType>(random->nextULessThan(kEdgeTypeCount)); - } else { - edgeType = kHairLine_EdgeType; - } - return GrEdgeEffect::Create(edgeType); -} diff --git a/src/gpu/effects/GrEdgeEffect.h b/src/gpu/effects/GrEdgeEffect.h deleted file mode 100644 index 5bbe05f623..0000000000 --- a/src/gpu/effects/GrEdgeEffect.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrEdgeEffect_DEFINED -#define GrEdgeEffect_DEFINED - -#include "GrEffect.h" - -class GrGLEdgeEffect; - -/** - * The output of this effect is one of three different edge types: hairlines, quads, - * and hairline quads. - */ - -class GrEdgeEffect : public GrEffect { -public: - enum EdgeType { - /* 1-pixel wide line - 2D implicit device coord line eq (a*x + b*y +c = 0). 4th component unused. */ - kHairLine_EdgeType = 0, - /* Quadratic specified by 0=u^2-v canonical coords. u and v are the first - two components of the vertex attribute. Coverage is based on signed - distance with negative being inside, positive outside. The edge is specified in - window space (y-down). If either the third or fourth component of the interpolated - vertex coord is > 0 then the pixel is considered outside the edge. This is used to - attempt to trim to a portion of the infinite quad. Requires shader derivative - instruction support. */ - kQuad_EdgeType, - /* Similar to above but for hairline quadratics. Uses unsigned distance. - Coverage is min(0, 1-distance). 3rd & 4th component unused. Requires - shader derivative instruction support. */ - kHairQuad_EdgeType, - - kLast_EdgeType = kHairQuad_EdgeType - }; - static const int kEdgeTypeCount = kLast_EdgeType + 1; - - static GrEffectRef* Create(EdgeType type) { - // we go through this so we only have one copy of each effect - static GrEffectRef* gEdgeEffectRef[kEdgeTypeCount] = { - CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrEdgeEffect, (kHairLine_EdgeType)))), - CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrEdgeEffect, (kQuad_EdgeType)))), - CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrEdgeEffect, (kHairQuad_EdgeType)))), - }; - static SkAutoTUnref<GrEffectRef> gUnref0(gEdgeEffectRef[0]); - static SkAutoTUnref<GrEffectRef> gUnref1(gEdgeEffectRef[1]); - static SkAutoTUnref<GrEffectRef> gUnref2(gEdgeEffectRef[2]); - - gEdgeEffectRef[type]->ref(); - return gEdgeEffectRef[type]; - } - - virtual ~GrEdgeEffect() {} - - static const char* Name() { return "Edge"; } - - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - - typedef GrGLEdgeEffect GLEffect; - - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; - - EdgeType edgeType() const { return fEdgeType; } - -private: - GrEdgeEffect(EdgeType edgeType); - - virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { - const GrEdgeEffect& qee = CastEffect<GrEdgeEffect>(other); - return qee.fEdgeType == fEdgeType; - } - - EdgeType fEdgeType; - - GR_DECLARE_EFFECT_TEST; - - typedef GrEffect INHERITED; -}; - -#endif diff --git a/src/gpu/effects/GrEllipseEdgeEffect.cpp b/src/gpu/effects/GrEllipseEdgeEffect.cpp deleted file mode 100644 index 7a773b0cde..0000000000 --- a/src/gpu/effects/GrEllipseEdgeEffect.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "GrEllipseEdgeEffect.h" -#include "gl/GrGLEffect.h" -#include "gl/GrGLSL.h" -#include "GrTBackendEffectFactory.h" - -class GrGLEllipseEdgeEffect : public GrGLEffect { -public: - GrGLEllipseEdgeEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) - : INHERITED (factory) {} - - virtual void emitCode(GrGLShaderBuilder* builder, - const GrDrawEffect& drawEffect, - EffectKey key, - const char* outputColor, - const char* inputColor, - const TextureSamplerArray& samplers) SK_OVERRIDE { - const GrEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<GrEllipseEdgeEffect>(); - - const char *vsCenterName, *fsCenterName; - const char *vsEdgeName, *fsEdgeName; - - builder->addVarying(kVec2f_GrSLType, "EllipseCenter", &vsCenterName, &fsCenterName); - const SkString* attr0Name = - builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[0]); - builder->vsCodeAppendf("\t%s = %s;\n", vsCenterName, attr0Name->c_str()); - - builder->addVarying(kVec4f_GrSLType, "EllipseEdge", &vsEdgeName, &fsEdgeName); - const SkString* attr1Name = - builder->getEffectAttributeName(drawEffect.getVertexAttribIndices()[1]); - builder->vsCodeAppendf("\t%s = %s;\n", vsEdgeName, attr1Name->c_str()); - - // translate to origin - builder->fsCodeAppendf("\tvec2 outerOffset = (%s.xy - %s.xy);\n", - builder->fragmentPosition(), fsCenterName); - builder->fsCodeAppend("\tvec2 innerOffset = outerOffset;\n"); - // scale y by xRadius/yRadius - builder->fsCodeAppendf("\touterOffset.y *= %s.y;\n", fsEdgeName); - builder->fsCodeAppend("\tfloat dOuter = length(outerOffset);\n"); - // compare outer lengths against xOuterRadius - builder->fsCodeAppendf("\tfloat edgeAlpha = clamp(%s.x-dOuter, 0.0, 1.0);\n", fsEdgeName); - - if (ellipseEffect.isStroked()) { - builder->fsCodeAppendf("\tinnerOffset.y *= %s.w;\n", fsEdgeName); - builder->fsCodeAppend("\tfloat dInner = length(innerOffset);\n"); - - // compare inner lengths against xInnerRadius - builder->fsCodeAppendf("\tfloat innerAlpha = clamp(dInner-%s.z, 0.0, 1.0);\n", fsEdgeName); - builder->fsCodeAppend("\tedgeAlpha *= innerAlpha;\n"); - } - - SkString modulate; - GrGLSLModulate4f(&modulate, inputColor, "edgeAlpha"); - builder->fsCodeAppendf("\t%s = %s;\n", outputColor, modulate.c_str()); - } - - static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { - const GrEllipseEdgeEffect& ellipseEffect = drawEffect.castEffect<GrEllipseEdgeEffect>(); - - return ellipseEffect.isStroked() ? 0x1 : 0x0; - } - - virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE { - } - -private: - typedef GrGLEffect INHERITED; -}; - -/////////////////////////////////////////////////////////////////////////////// - -GrEllipseEdgeEffect::GrEllipseEdgeEffect(bool stroke) : GrEffect() { - this->addVertexAttrib(kVec2f_GrSLType); - this->addVertexAttrib(kVec4f_GrSLType); - - fStroke = stroke; -} - -void GrEllipseEdgeEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { - *validFlags = 0; -} - -const GrBackendEffectFactory& GrEllipseEdgeEffect::getFactory() const { - return GrTBackendEffectFactory<GrEllipseEdgeEffect>::getInstance(); -} - -/////////////////////////////////////////////////////////////////////////////// - -GR_DEFINE_EFFECT_TEST(GrEllipseEdgeEffect); - -GrEffectRef* GrEllipseEdgeEffect::TestCreate(SkMWCRandom* random, - GrContext* context, - const GrDrawTargetCaps&, - GrTexture* textures[]) { - return GrEllipseEdgeEffect::Create(random->nextBool()); -} diff --git a/src/gpu/effects/GrEllipseEdgeEffect.h b/src/gpu/effects/GrEllipseEdgeEffect.h deleted file mode 100644 index a491f999b2..0000000000 --- a/src/gpu/effects/GrEllipseEdgeEffect.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef GrEllipseEdgeEffect_DEFINED -#define GrEllipseEdgeEffect_DEFINED - -#include "GrEffect.h" - -class GrGLEllipseEdgeEffect; - -/** - * The output of this effect is a modulation of the input color and coverage for an axis-aligned - * ellipse, specified as center_x, center_y, x_radius, x_radius/y_radius in window space (y-down). - */ - -class GrEllipseEdgeEffect : public GrEffect { -public: - static GrEffectRef* Create(bool stroke) { - // we go through this so we only have one copy of each effect (stroked/filled) - static SkAutoTUnref<GrEffectRef> gEllipseStrokeEdgeEffectRef( - CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrEllipseEdgeEffect, (true))))); - static SkAutoTUnref<GrEffectRef> gEllipseFillEdgeEffectRef( - CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrEllipseEdgeEffect, (false))))); - - if (stroke) { - gEllipseStrokeEdgeEffectRef.get()->ref(); - return gEllipseStrokeEdgeEffectRef; - } else { - gEllipseFillEdgeEffectRef.get()->ref(); - return gEllipseFillEdgeEffectRef; - } - } - - virtual ~GrEllipseEdgeEffect() {} - - static const char* Name() { return "EllipseEdge"; } - - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; - - typedef GrGLEllipseEdgeEffect GLEffect; - - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; - - inline bool isStroked() const { return fStroke; } - -private: - GrEllipseEdgeEffect(bool stroke); - - virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { - const GrEllipseEdgeEffect& eee = CastEffect<GrEllipseEdgeEffect>(other); - return eee.fStroke == fStroke; - } - - bool fStroke; - - GR_DECLARE_EFFECT_TEST; - - typedef GrEffect INHERITED; -}; - -#endif |