aboutsummaryrefslogtreecommitdiffhomepage
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
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
-rw-r--r--gm/convexpolyeffect.cpp68
-rw-r--r--src/gpu/GrClipMaskManager.cpp2
-rw-r--r--src/gpu/effects/GrConvexPolyEffect.cpp73
-rw-r--r--src/gpu/effects/GrConvexPolyEffect.h8
4 files changed, 94 insertions, 57 deletions
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 2632bd4186..9142ca9cbd 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -44,7 +44,7 @@ protected:
}
virtual SkISize onISize() SK_OVERRIDE {
- return make_isize(475, 800);
+ return make_isize(720, 800);
}
virtual uint32_t onGetFlags() const SK_OVERRIDE {
@@ -100,7 +100,6 @@ protected:
fRects.addToTail(SkRect::MakeLTRB(5.05f, .55f, 5.45f, .85f));
// inverted in x and y
fRects.addToTail(SkRect::MakeLTRB(100.f, 50.5f, 5.f, 0.5f));
-
}
virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
@@ -174,55 +173,58 @@ protected:
y += SkScalarCeilToScalar(path->getBounds().height() + 20.f);
}
- // Draw rects. We only have specialized effect code for the AA case, so don't do non-AA.
for (SkTLList<SkRect>::Iter iter(fRects, SkTLList<SkRect>::Iter::kHead_IterStart);
NULL != iter.get();
iter.next()) {
SkScalar x = 0;
- GrTestTarget tt;
- context->getTestTarget(&tt);
- if (NULL == tt.target()) {
- SkDEBUGFAIL("Couldn't get Gr test target.");
- return;
- }
-
- SkRect rect = *iter.get();
- rect.offset(x, y);
- SkAutoTUnref<GrEffectRef> effect(GrConvexPolyEffect::CreateForAAFillRect(rect));
- if (!effect) {
- SkDEBUGFAIL("Couldn't create convex poly effect.");
- return;
- }
+ for (int et = 0; et < GrConvexPolyEffect::kEdgeTypeCnt; ++et) {
+ GrTestTarget tt;
+ context->getTestTarget(&tt);
+ if (NULL == tt.target()) {
+ SkDEBUGFAIL("Couldn't get Gr test target.");
+ return;
+ }
+ SkRect rect = *iter.get();
+ rect.offset(x, y);
+ GrConvexPolyEffect::EdgeType edgeType = (GrConvexPolyEffect::EdgeType) et;
+ SkAutoTUnref<GrEffectRef> effect(GrConvexPolyEffect::Create(edgeType, rect));
+ if (!effect) {
+ SkDEBUGFAIL("Couldn't create convex poly effect.");
+ return;
+ }
- GrDrawState* drawState = tt.target()->drawState();
- drawState->setVertexAttribs<kAttribs>(SK_ARRAY_COUNT(kAttribs));
- drawState->addCoverageEffect(effect, 1);
- drawState->setIdentityViewMatrix();
- drawState->setRenderTarget(rt);
- drawState->setColor(0xff000000);
+ GrDrawState* drawState = tt.target()->drawState();
+ drawState->setVertexAttribs<kAttribs>(SK_ARRAY_COUNT(kAttribs));
+ drawState->addCoverageEffect(effect, 1);
+ drawState->setIdentityViewMatrix();
+ drawState->setRenderTarget(rt);
+ drawState->setColor(0xff000000);
- SkPoint verts[4];
- SkRect bounds = rect;
- bounds.outset(5.f, 5.f);
- bounds.toQuad(verts);
+ SkPoint verts[4];
+ SkRect bounds = rect;
+ bounds.outset(5.f, 5.f);
+ bounds.toQuad(verts);
- tt.target()->setVertexSourceToArray(verts, 4);
- tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
- tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+ tt.target()->setVertexSourceToArray(verts, 4);
+ tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
+ tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
- x += SkScalarCeilToScalar(rect.width() + 10.f);
+ x += SkScalarCeilToScalar(rect.width() + 10.f);
+ }
- // Draw AA rect using normal API for reference
+ // Draw rect without and with AA using normal API for reference
canvas->save();
canvas->translate(x, y);
SkPaint paint;
+ canvas->drawRect(*iter.get(), paint);
+ x += SkScalarCeilToScalar(iter.get()->width() + 10.f);
paint.setAntiAlias(true);
canvas->drawRect(*iter.get(), paint);
canvas->restore();
- y += SkScalarCeilToScalar(rect.height() + 20.f);
+ y += SkScalarCeilToScalar(iter.get()->height() + 20.f);
}
}
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index b637bd6c7a..90106fa7e0 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -200,7 +200,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
SkIntToScalar(-clipDataIn->fOrigin.fY) };
rect.offset(offset);
- effect.reset(GrConvexPolyEffect::CreateForAAFillRect(rect));
+ effect.reset(GrConvexPolyEffect::Create(GrConvexPolyEffect::kFillAA_EdgeType, rect));
// This should never fail.
SkASSERT(effect);
}
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();