Chromium Code Reviews| Index: src/gpu/effects/GrConvexPolyEffect.cpp |
| diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp |
| index e47ed0f86606b93d42913c8ad298023fefa4e276..c1a54881d9bd77d3ec937b25288f969b84dd246b 100644 |
| --- a/src/gpu/effects/GrConvexPolyEffect.cpp |
| +++ b/src/gpu/effects/GrConvexPolyEffect.cpp |
| @@ -14,6 +14,136 @@ |
| #include "SkPath.h" |
| +////////////////////////////////////////////////////////////////////////////// |
| +class GLAARectEffect; |
| + |
| +class AARectEffect : public GrEffect { |
| +public: |
| + typedef GLAARectEffect GLEffect; |
| + |
| + 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)))); |
| + } |
| + |
| + virtual void getConstantColorComponents(GrColor* color, |
| + uint32_t* validFlags) const SK_OVERRIDE { |
| + if (fRect.isEmpty()) { |
| + // An empty rect will have no coverage anywhere. |
| + *color = 0x00000000; |
| + *validFlags = kRGBA_GrColorComponentFlags; |
| + } else { |
| + *validFlags = 0; |
| + } |
| + } |
| + |
| + virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
| + |
| +private: |
| + AARectEffect(const SkRect& rect) : fRect(rect) { |
| + this->setWillReadFragmentPosition(); |
| + } |
| + |
| + virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { |
| + const AARectEffect& aare = CastEffect<AARectEffect>(other); |
| + return fRect == aare.fRect; |
| + } |
| + |
| + SkRect fRect; |
| + typedef GrEffect INHERITED; |
| + |
| + GR_DECLARE_EFFECT_TEST; |
| + |
| +}; |
| + |
| +GR_DEFINE_EFFECT_TEST(AARectEffect); |
| + |
| +GrEffectRef* AARectEffect::TestCreate(SkRandom* random, |
| + GrContext*, |
| + const GrDrawTargetCaps& caps, |
| + GrTexture*[]) { |
| + SkRect rect = SkRect::MakeLTRB(random->nextSScalar1(), |
| + random->nextSScalar1(), |
| + random->nextSScalar1(), |
| + random->nextSScalar1()); |
| + return AARectEffect::Create(rect); |
| +} |
| + |
| +////////////////////////////////////////////////////////////////////////////// |
| + |
| +class GLAARectEffect : public GrGLEffect { |
| +public: |
| + GLAARectEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
| + |
| + virtual void emitCode(GrGLShaderBuilder* builder, |
| + const GrDrawEffect& drawEffect, |
| + EffectKey key, |
| + const char* outputColor, |
| + const char* inputColor, |
| + const TransformedCoordsArray&, |
| + const TextureSamplerArray&) SK_OVERRIDE; |
| + |
| + static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&) { return 0; } |
| + |
| + virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE; |
| + |
| +private: |
| + GrGLUniformManager::UniformHandle fRectUniform; |
| + SkRect fPrevRect; |
| + typedef GrGLEffect INHERITED; |
| +}; |
| + |
| +GLAARectEffect::GLAARectEffect(const GrBackendEffectFactory& factory, |
| + const GrDrawEffect& drawEffect) |
|
robertphillips
2014/02/04 19:38:50
tab here?
bsalomon
2014/02/08 19:18:01
Done.
|
| +: INHERITED (factory) { |
| + fPrevRect.fLeft = SK_ScalarNaN; |
| +} |
| + |
| +void GLAARectEffect::emitCode(GrGLShaderBuilder* builder, |
| + const GrDrawEffect& drawEffect, |
| + EffectKey key, |
| + const char* outputColor, |
| + const char* inputColor, |
| + const TransformedCoordsArray&, |
| + const TextureSamplerArray& samplers) { |
| + const char *rectName; |
| + 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. |
|
robertphillips
2014/02/04 19:38:50
Maybe a more expansive comment about how coverage
bsalomon
2014/02/08 19:18:01
Done.
|
| + 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); |
| + builder->fsCodeAppendf("\t\tfloat alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));\n"); |
| + |
| + builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, |
| + (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); |
| +} |
| + |
| +void GLAARectEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) { |
| + const AARectEffect& aare = drawEffect.castEffect<AARectEffect>(); |
| + const SkRect& rect = aare.getRect(); |
|
robertphillips
2014/02/04 19:38:50
Do you think this caching will actually pay off?
bsalomon
2014/02/08 19:18:01
We can have the same clip active for a lot of draw
|
| + if (rect != fPrevRect) { |
| + uman.set4f(fRectUniform, rect.fLeft + 0.5f, rect.fTop + 0.5f, |
| + rect.fRight - 0.5f, rect.fBottom - 0.5f); |
| + fPrevRect = rect; |
| + } |
| +} |
| + |
| +const GrBackendEffectFactory& AARectEffect::getFactory() const { |
| + return GrTBackendEffectFactory<AARectEffect>::getInstance(); |
| +} |
| + |
| +////////////////////////////////////////////////////////////////////////////// |
| + |
| class GrGLConvexPolyEffect : public GrGLEffect { |
| public: |
| GrGLConvexPolyEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
| @@ -75,7 +205,7 @@ void GrGLConvexPolyEffect::emitCode(GrGLShaderBuilder* builder, |
| } |
| } |
| - builder->fsCodeAppendf("\t%s = %s;\n", outputColor, |
| + builder->fsCodeAppendf("\t\t%s = %s;\n", outputColor, |
| (GrGLSLExpr4(inputColor) * GrGLSLExpr1("alpha")).c_str()); |
| } |
| @@ -134,6 +264,16 @@ GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkPath& path) { |
| return Create(type, n, edges); |
| } |
| +GrEffectRef* GrConvexPolyEffect::Create(EdgeType type, const SkRect& rect) { |
| + if (type == kFillAA_EdgeType) { |
| + return AARectEffect::Create(rect); |
| + } else { |
|
robertphillips
2014/02/04 19:38:50
It seems like we would never want to take this pat
bsalomon
2014/02/08 19:18:01
True. I changed the function to CreateAAFillRect a
|
| + SkPath path; |
| + path.addRect(rect); |
| + return Create(type, path); |
| + } |
| +} |
| + |
| GrConvexPolyEffect::~GrConvexPolyEffect() {} |
| void GrConvexPolyEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { |