Index: src/gpu/effects/GrConvexPolyEffect.cpp |
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp |
index bbfa3bb82cb73cad3c6d15daccc90c4c6d64bbd3..baad92837c233721542a4d723bb3c354d154824b 100644 |
--- a/src/gpu/effects/GrConvexPolyEffect.cpp |
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp |
@@ -19,13 +19,14 @@ class GLAARectEffect; |
class AARectEffect : public GrEffect { |
public: |
typedef GLAARectEffect GLEffect; |
+ typedef GrConvexPolyEffect::EdgeType EdgeType; |
const SkRect& getRect() const { return fRect; } |
static const char* Name() { return "AARect"; } |
- static GrEffectRef* Create(const SkRect& rect) { |
- return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (rect)))); |
+ static GrEffectRef* Create(EdgeType edgeType, const SkRect& rect) { |
+ return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(AARectEffect, (edgeType, rect)))); |
} |
virtual void getConstantColorComponents(GrColor* color, |
@@ -39,10 +40,12 @@ public: |
} |
} |
+ GrConvexPolyEffect::EdgeType getEdgeType() const { return fEdgeType; } |
+ |
virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
private: |
- AARectEffect(const SkRect& rect) : fRect(rect) { |
+ AARectEffect(EdgeType edgeType, const SkRect& rect) : fRect(rect), fEdgeType(edgeType) { |
this->setWillReadFragmentPosition(); |
} |
@@ -52,6 +55,8 @@ private: |
} |
SkRect fRect; |
+ EdgeType fEdgeType; |
+ |
typedef GrEffect INHERITED; |
GR_DECLARE_EFFECT_TEST; |
@@ -64,11 +69,14 @@ GrEffectRef* AARectEffect::TestCreate(SkRandom* random, |
GrContext*, |
const GrDrawTargetCaps& caps, |
GrTexture*[]) { |
+ EdgeType edgeType = static_cast<EdgeType>( |
+ random->nextULessThan(GrConvexPolyEffect::kEdgeTypeCnt)); |
+ |
SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(), |
random->nextSScalar1(), |
random->nextSScalar1(), |
random->nextSScalar1()); |
- return AARectEffect::Create(rect); |
+ return AARectEffect::Create(edgeType, rect); |
} |
////////////////////////////////////////////////////////////////////////////// |
@@ -85,7 +93,7 @@ public: |
const TransformedCoordsArray&, |
const TextureSamplerArray&) SK_OVERRIDE; |
- static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; } |
+ static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); |
virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; |
@@ -108,23 +116,39 @@ void GLAARectEffect::emitCode(GrGLShaderBuilder* builder, |
const char* inputColor, |
const TransformedCoordsArray&, |
const TextureSamplerArray& samplers) { |
+ const AARectEffect& aare = drawEffect.castEffect<AARectEffect>(); |
const char *rectName; |
+ // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), |
+ // respectively. |
fRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
kVec4f_GrSLType, |
"rect", |
&rectName); |
const char* fragmentPos = builder->fragmentPosition(); |
- // The rect uniform's xyzw refer to (left + 0.5, top + 0.5, right - 0.5, bottom - 0.5), |
- // respectively. The amount of coverage removed in x and y by the edges is computed as a pair of |
- // negative numbers, xSub and ySub. |
- builder->fsCodeAppend("\t\tfloat xSub, ySub;\n"); |
- builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName); |
- builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos); |
- builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName); |
- builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos); |
- // Now compute coverage in x and y and multiply them to get the fraction of the pixel covered. |
- builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); |
+ if (GrConvexPolyEffect::kFillAA_EdgeType == aare.getEdgeType() || |
+ GrConvexPolyEffect::kInverseFillAA_EdgeType == aare.getEdgeType()) { |
+ // The amount of coverage removed in x and y by the edges is computed as a pair of negative |
+ // numbers, xSub and ySub. |
+ builder->fsCodeAppend("\t\tfloat xSub, ySub;\n"); |
+ builder->fsCodeAppendf("\t\txSub = min(%s.x - %s.x, 0.0);\n", fragmentPos, rectName); |
+ builder->fsCodeAppendf("\t\txSub += min(%s.z - %s.x, 0.0);\n", rectName, fragmentPos); |
+ builder->fsCodeAppendf("\t\tySub = min(%s.y - %s.y, 0.0);\n", fragmentPos, rectName); |
+ builder->fsCodeAppendf("\t\tySub += min(%s.w - %s.y, 0.0);\n", rectName, fragmentPos); |
+ // Now compute coverage in x and y and multiply them to get the fraction of the pixel |
+ // covered. |
+ builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); |
+ } else { |
+ builder->fsCodeAppendf("\t\tfloat alpha = 1.0;\n"); |
+ builder->fsCodeAppendf("\t\talpha *= (%s.x - %s.x) > -0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); |
+ builder->fsCodeAppendf("\t\talpha *= (%s.z - %s.x) > -0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); |
+ builder->fsCodeAppendf("\t\talpha *= (%s.y - %s.y) > 0.5 ? 1.0 : 0.0;\n", fragmentPos, rectName); |
+ builder->fsCodeAppendf("\t\talpha *= (%s.w - %s.y) > 0.5 ? 1.0 : 0.0;\n", rectName, fragmentPos); |
+ } |
+ if (GrConvexPolyEffect::kInverseFillAA_EdgeType == aare.getEdgeType() || |
+ GrConvexPolyEffect::kInverseFillNoAA_EdgeType == aare.getEdgeType()) { |
+ builder->fsCodeAppend("\t\talpha = 1.0 - alpha;\n"); |
+ } |
builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, |
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); |
} |
@@ -139,6 +163,11 @@ void GLAARectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& |
} |
} |
+GrGLEffect::EffectKey GLAARectEffect::GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { |
+ const AARectEffect& aare = drawEffect.castEffect<AARectEffect>(); |
+ return aare.getEdgeType(); |
+} |
+ |
const GrBackendEffectFactory& AARectEffect::getFactory() const { |
return GrTBackendEffectFactory<AARectEffect>::getInstance(); |
} |
@@ -196,20 +225,26 @@ void GrGLConvexPolyEffect::emitCode(GrGLShaderBuilder* builder, |
edgeArrayName, i, fragmentPos, fragmentPos); |
switch (cpe.getEdgeType()) { |
case GrConvexPolyEffect::kFillAA_EdgeType: |
+ case GrConvexPolyEffect::kInverseFillAA_EdgeType: // inverse handled at the end |
builder->fsCodeAppend("\t\tedge = clamp(edge, 0.0, 1.0);\n"); |
- builder->fsCodeAppend("\t\talpha *= edge;\n"); |
break; |
case GrConvexPolyEffect::kFillNoAA_EdgeType: |
+ case GrConvexPolyEffect::kInverseFillNoAA_EdgeType: // inverse handled at the end |
builder->fsCodeAppend("\t\tedge = edge >= 0.5 ? 1.0 : 0.0;\n"); |
- builder->fsCodeAppend("\t\talpha *= edge;\n"); |
break; |
} |
+ builder->fsCodeAppend("\t\talpha *= edge;\n"); |
} |
// Woe is me. See skbug.com/2149. |
if (kTegra2_GrGLRenderer == builder->ctxInfo().renderer()) { |
builder->fsCodeAppend("\t\tif (-1.0 == alpha) {\n\t\t\tdiscard;\n\t\t}\n"); |
} |
+ |
+ if (GrConvexPolyEffect::kInverseFillAA_EdgeType == cpe.getEdgeType() || |
+ GrConvexPolyEffect::kInverseFillNoAA_EdgeType == cpe.getEdgeType() ) { |
+ builder->fsCodeAppend("\talpha = 1.0 - alpha;\n"); |
+ } |
builder->fsCodeAppendf("\t%s = %s;\n", outputColor, |
(GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); |
} |
@@ -277,8 +312,8 @@ GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkPath& path, const |
return Create(type, n, edges); |
} |
-GrEffectRef* GrConvexPolyEffect::CreateForAAFillRect(const SkRect& rect) { |
- return AARectEffect::Create(rect); |
+GrEffectRef* GrConvexPolyEffect::Create(EdgeType edgeType, const SkRect& rect) { |
+ return AARectEffect::Create(edgeType, rect); |
} |
GrConvexPolyEffect::~GrConvexPolyEffect() {} |