diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-02-28 14:43:26 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-02-28 14:43:26 +0000 |
commit | d85f32ca40475fb246dd8ca93abaf1c3db0389e1 (patch) | |
tree | 304e4e86f0b78af001428f36976cf10a85f4424a /src/gpu/effects | |
parent | 392c9be344549e809d0468abafdbeb6e32135bcd (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.cpp | 73 | ||||
-rw-r--r-- | src/gpu/effects/GrConvexPolyEffect.h | 8 |
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(); |