aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-02-28 14:43:26 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-02-28 14:43:26 +0000
commitd85f32ca40475fb246dd8ca93abaf1c3db0389e1 (patch)
tree304e4e86f0b78af001428f36976cf10a85f4424a /src/gpu/effects
parent392c9be344549e809d0468abafdbeb6e32135bcd (diff)
Make GrConvexPolyEffect support inverse fills and non-AA rects
BUG=skia:2151 R=robertphillips@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/183833003 git-svn-id: http://skia.googlecode.com/svn/trunk@13621 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/effects')
-rw-r--r--src/gpu/effects/GrConvexPolyEffect.cpp73
-rw-r--r--src/gpu/effects/GrConvexPolyEffect.h8
2 files changed, 58 insertions, 23 deletions
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index bbfa3bb82c..baad92837c 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() {}
diff --git a/src/gpu/effects/GrConvexPolyEffect.h b/src/gpu/effects/GrConvexPolyEffect.h
index c712eb3af8..ab9d313c16 100644
--- a/src/gpu/effects/GrConvexPolyEffect.h
+++ b/src/gpu/effects/GrConvexPolyEffect.h
@@ -21,13 +21,13 @@ class SkPath;
*/
class GrConvexPolyEffect : public GrEffect {
public:
- /** This could be expanded to include a AA hairline mode. If so, unify with GrBezierEffect's
- enum. */
enum EdgeType {
kFillNoAA_EdgeType,
kFillAA_EdgeType,
+ kInverseFillNoAA_EdgeType,
+ kInverseFillAA_EdgeType,
- kLastEdgeType = kFillAA_EdgeType,
+ kLastEdgeType = kInverseFillAA_EdgeType,
};
enum {
@@ -64,7 +64,7 @@ public:
/**
* Creates an effect that fills inside the rect with AA edges..
*/
- static GrEffectRef* CreateForAAFillRect(const SkRect&);
+ static GrEffectRef* Create(EdgeType, const SkRect&);
virtual ~GrConvexPolyEffect();