| Index: src/effects/SkBlurMaskFilter.cpp
|
| diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
|
| index c4069ca36a8eba397568d1cbaeb5428c3d1f3c71..f5c80f23055364d62a4b52b01e72e381a36890a3 100644
|
| --- a/src/effects/SkBlurMaskFilter.cpp
|
| +++ b/src/effects/SkBlurMaskFilter.cpp
|
| @@ -25,7 +25,6 @@
|
| #include "effects/GrSimpleTextureEffect.h"
|
| #include "GrTBackendEffectFactory.h"
|
| #include "SkGrPixelRef.h"
|
| -#include "SkDraw.h"
|
| #endif
|
|
|
| class SkBlurMaskFilterImpl : public SkMaskFilter {
|
| @@ -252,9 +251,9 @@ static bool rect_exceeds(const SkRect& r, SkScalar v) {
|
| }
|
|
|
| #ifdef SK_IGNORE_FAST_RRECT_BLUR
|
| -SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect", false, "Use the faster analytic blur approach for ninepatch rects" );
|
| +SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticRRect", false, "Use the faster analytic blur approach for ninepatch rects" );
|
| #else
|
| -SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect", true, "Use the faster analytic blur approach for ninepatch round rects" );
|
| +SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticRRect", true, "Use the faster analytic blur approach for ninepatch round rects" );
|
| #endif
|
|
|
| SkMaskFilter::FilterReturn
|
| @@ -810,290 +809,11 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context,
|
| return true;
|
| }
|
|
|
| -class GrGLRRectBlurEffect;
|
| -
|
| -class GrRRectBlurEffect : public GrEffect {
|
| -public:
|
| -
|
| - static GrEffectRef* Create(GrContext* context, float sigma, const SkRRect&);
|
| -
|
| - virtual ~GrRRectBlurEffect() {};
|
| - static const char* Name() { return "GrRRectBlur"; }
|
| -
|
| - const SkRRect& getRRect() const { return fRRect; }
|
| - float getSigma() const { return fSigma; }
|
| -
|
| - typedef GrGLRRectBlurEffect GLEffect;
|
| -
|
| - virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE;
|
| -
|
| - virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
|
| -
|
| -private:
|
| - GrRRectBlurEffect(float sigma, const SkRRect&, GrTexture* profileTexture);
|
| -
|
| - virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
|
| -
|
| - SkRRect fRRect;
|
| - float fSigma;
|
| - GrTextureAccess fNinePatchAccess;
|
| -
|
| - GR_DECLARE_EFFECT_TEST;
|
| -
|
| - typedef GrEffect INHERITED;
|
| -};
|
| -
|
| -
|
| -GrEffectRef* GrRRectBlurEffect::Create(GrContext* context, float sigma, const SkRRect& rrect) {
|
| - if (!rrect.isSimpleCircular()) {
|
| - SkDebugf( "not simple circular\n" );
|
| - return NULL;
|
| - }
|
| -
|
| - // Make sure we can successfully ninepatch this rrect -- the blur sigma has to be
|
| - // sufficiently small relative to both the size of the corner radius and the
|
| - // width (and height) of the rrect.
|
| -
|
| - unsigned int blurRadius = 3*SkScalarCeilToInt(sigma-1/6.0f);
|
| - unsigned int cornerRadius = SkScalarCeilToInt(rrect.getSimpleRadii().x());
|
| - if (cornerRadius + blurRadius > rrect.width()/2 ||
|
| - cornerRadius + blurRadius > rrect.height()/2) {
|
| - return NULL;
|
| - }
|
| -
|
| - static const GrCacheID::Domain gRRectBlurDomain = GrCacheID::GenerateDomain();
|
| - GrCacheID::Key key;
|
| - memset(&key, 0, sizeof(key));
|
| - key.fData32[0] = blurRadius;
|
| - key.fData32[1] = cornerRadius;
|
| - GrCacheID blurRRectNinePatchID(gRRectBlurDomain, key);
|
| -
|
| - GrTextureParams params;
|
| - params.setFilterMode(GrTextureParams::kBilerp_FilterMode);
|
| -
|
| - unsigned int smallRectSide = 2*(blurRadius + cornerRadius) + 1;
|
| - unsigned int texSide = smallRectSide + 2*blurRadius;
|
| - GrTextureDesc texDesc;
|
| - texDesc.fWidth = texSide;
|
| - texDesc.fHeight = texSide;
|
| - texDesc.fConfig = kAlpha_8_GrPixelConfig;
|
| -
|
| - GrTexture *blurNinePatchTexture = context->findAndRefTexture(texDesc, blurRRectNinePatchID,
|
| - ¶ms);
|
| -
|
| - if (NULL == blurNinePatchTexture) {
|
| - SkMask mask;
|
| -
|
| - mask.fBounds = SkIRect::MakeWH(smallRectSide, smallRectSide);
|
| - mask.fFormat = SkMask::kA8_Format;
|
| - mask.fRowBytes = mask.fBounds.width();
|
| - mask.fImage = SkMask::AllocImage(mask.computeTotalImageSize());
|
| - SkAutoMaskFreeImage amfi(mask.fImage);
|
| -
|
| - memset(mask.fImage, 0, mask.computeTotalImageSize());
|
| -
|
| - SkRect smallRect;
|
| - smallRect.setWH(SkIntToScalar(smallRectSide), SkIntToScalar(smallRectSide));
|
| -
|
| - SkRRect smallRRect;
|
| - smallRRect.setRectXY(smallRect, SkIntToScalar(cornerRadius), SkIntToScalar(cornerRadius));
|
| -
|
| - SkPath path;
|
| - path.addRRect( smallRRect );
|
| -
|
| - SkDraw::DrawToMask(path, &mask.fBounds, NULL, NULL, &mask,
|
| - SkMask::kJustRenderImage_CreateMode, SkPaint::kFill_Style);
|
| -
|
| - SkMask blurred_mask;
|
| - SkBlurMask::BoxBlur(&blurred_mask, mask, sigma, kNormal_SkBlurStyle,
|
| - kHigh_SkBlurQuality, NULL, true );
|
| -
|
| - blurNinePatchTexture = context->createTexture(¶ms, texDesc, blurRRectNinePatchID,
|
| - blurred_mask.fImage, 0);
|
| - }
|
| -
|
| - if (NULL == blurNinePatchTexture) {
|
| - return NULL;
|
| - }
|
| -
|
| - return CreateEffectRef(AutoEffectUnref(SkNEW_ARGS(GrRRectBlurEffect,
|
| - (sigma, rrect, blurNinePatchTexture))));
|
| -}
|
| -
|
| -void GrRRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const {
|
| - *validFlags = 0;
|
| -}
|
| -
|
| -const GrBackendEffectFactory& GrRRectBlurEffect::getFactory() const {
|
| - return GrTBackendEffectFactory<GrRRectBlurEffect>::getInstance();
|
| -}
|
| -
|
| -GrRRectBlurEffect::GrRRectBlurEffect(float sigma, const SkRRect& rrect, GrTexture *ninePatchTexture)
|
| - : fRRect(rrect)
|
| - , fSigma(sigma)
|
| - , fNinePatchAccess(ninePatchTexture)
|
| -{
|
| - this->addTextureAccess(&fNinePatchAccess);
|
| - this->setWillReadFragmentPosition();
|
| -}
|
| -
|
| -bool GrRRectBlurEffect::onIsEqual(const GrEffect& other) const {
|
| - const GrRRectBlurEffect& rrbe = CastEffect<GrRRectBlurEffect>(other);
|
| - return fRRect.getSimpleRadii().fX == rrbe.fRRect.getSimpleRadii().fX && fSigma == rrbe.fSigma;
|
| -}
|
| -
|
| -//////////////////////////////////////////////////////////////////////////////
|
| -
|
| -GR_DEFINE_EFFECT_TEST(GrRRectBlurEffect);
|
| -
|
| -GrEffectRef* GrRRectBlurEffect::TestCreate(SkRandom* random,
|
| - GrContext* context,
|
| - const GrDrawTargetCaps& caps,
|
| - GrTexture*[]) {
|
| - SkScalar w = random->nextRangeScalar(100.f, 1000.f);
|
| - SkScalar h = random->nextRangeScalar(100.f, 1000.f);
|
| - SkScalar r = random->nextRangeF(1.f, 9.f);
|
| - SkScalar sigma = random->nextRangeF(1.f,20.f);
|
| - SkRRect rrect;
|
| - rrect.setRectXY(SkRect::MakeWH(w, h), r, r);
|
| - return GrRRectBlurEffect::Create(context, sigma, rrect);
|
| -}
|
| -
|
| -//////////////////////////////////////////////////////////////////////////////
|
| -
|
| -class GrGLRRectBlurEffect : public GrGLEffect {
|
| -public:
|
| - GrGLRRectBlurEffect(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;
|
| -
|
| - virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVERRIDE;
|
| -
|
| -private:
|
| - GrGLUniformManager::UniformHandle fProxyRectUniform;
|
| - GrGLUniformManager::UniformHandle fCornerRadiusUniform;
|
| - GrGLUniformManager::UniformHandle fBlurRadiusUniform;
|
| - typedef GrGLEffect INHERITED;
|
| -};
|
| -
|
| -GrGLRRectBlurEffect::GrGLRRectBlurEffect(const GrBackendEffectFactory& factory,
|
| - const GrDrawEffect& drawEffect)
|
| - : INHERITED (factory) {
|
| -}
|
| -
|
| -void GrGLRRectBlurEffect::emitCode(GrGLShaderBuilder* builder,
|
| - const GrDrawEffect& drawEffect,
|
| - EffectKey key,
|
| - const char* outputColor,
|
| - const char* inputColor,
|
| - const TransformedCoordsArray&,
|
| - const TextureSamplerArray& samplers) {
|
| - const char *rectName;
|
| - const char *cornerRadiusName;
|
| - const char *blurRadiusName;
|
| -
|
| - // The proxy rect has left, top, right, and bottom edges correspond to
|
| - // components x, y, z, and w, respectively.
|
| -
|
| - fProxyRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
|
| - kVec4f_GrSLType,
|
| - "proxyRect",
|
| - &rectName);
|
| - fCornerRadiusUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
|
| - kFloat_GrSLType,
|
| - "cornerRadius",
|
| - &cornerRadiusName);
|
| - fBlurRadiusUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility,
|
| - kFloat_GrSLType,
|
| - "blurRadius",
|
| - &blurRadiusName);
|
| - const char* fragmentPos = builder->fragmentPosition();
|
| -
|
| - // warp the fragment position to the appropriate part of the 9patch blur texture
|
| -
|
| - builder->fsCodeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectName, rectName);
|
| - builder->fsCodeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", fragmentPos, rectName);
|
| - builder->fsCodeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusName, blurRadiusName );
|
| - builder->fsCodeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n", rectName, rectName );
|
| -
|
| - builder->fsCodeAppendf("\t\tif (translatedFragPos.x >= threshold && translatedFragPos.x < (middle.x+threshold)) {\n" );
|
| - builder->fsCodeAppendf("\t\t\ttranslatedFragPos.x = threshold;\n");
|
| - builder->fsCodeAppendf("\t\t} else if (translatedFragPos.x >= (middle.x + threshold)) {\n");
|
| - builder->fsCodeAppendf("\t\t\ttranslatedFragPos.x -= middle.x;\n");
|
| - builder->fsCodeAppendf("\t\t}\n");
|
| -
|
| - builder->fsCodeAppendf("\t\tif (translatedFragPos.y > threshold && translatedFragPos.y < (middle.y+threshold)) {\n" );
|
| - builder->fsCodeAppendf("\t\t\ttranslatedFragPos.y = threshold;\n");
|
| - builder->fsCodeAppendf("\t\t} else if (translatedFragPos.y >= (middle.y + threshold)) {\n");
|
| - builder->fsCodeAppendf("\t\t\ttranslatedFragPos.y -= middle.y;\n");
|
| - builder->fsCodeAppendf("\t\t}\n");
|
| -
|
| - builder->fsCodeAppendf("\t\tvec2 proxyDims = vec2(2.0*threshold+1.0);\n");
|
| - builder->fsCodeAppendf("\t\tvec2 texCoord = translatedFragPos / proxyDims;\n");
|
| -
|
| - builder->fsCodeAppendf("\t%s = ", outputColor);
|
| - builder->fsAppendTextureLookupAndModulate(inputColor, samplers[0], "texCoord");
|
| - builder->fsCodeAppend(";\n");
|
| -}
|
| -
|
| -void GrGLRRectBlurEffect::setData(const GrGLUniformManager& uman,
|
| - const GrDrawEffect& drawEffect) {
|
| - const GrRRectBlurEffect& brre = drawEffect.castEffect<GrRRectBlurEffect>();
|
| - SkRRect rrect = brre.getRRect();
|
| -
|
| - float blurRadius = 3.f*SkScalarCeilToScalar(brre.getSigma()-1/6.0f);
|
| - uman.set1f(fBlurRadiusUniform, blurRadius);
|
| -
|
| - SkRect rect = rrect.getBounds();
|
| - rect.outset(blurRadius, blurRadius);
|
| - uman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
|
| -
|
| - SkScalar radius = 0;
|
| - SkASSERT(rrect.isSimpleCircular() || rrect.isRect());
|
| - radius = rrect.getSimpleRadii().fX;
|
| - uman.set1f(fCornerRadiusUniform, radius);
|
| -}
|
| -
|
| -
|
| bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context,
|
| GrPaint* grp,
|
| const SkStrokeRec& strokeRec,
|
| const SkRRect& rrect) const {
|
| - if (fBlurStyle != kNormal_SkBlurStyle) {
|
| - return false;
|
| - }
|
| -
|
| - if (!strokeRec.isFillStyle()) {
|
| - return false;
|
| - }
|
| -
|
| - SkRect proxy_rect = rrect.rect();
|
| - SkMatrix ctm = context->getMatrix();
|
| - SkScalar xformedSigma = this->computeXformedSigma(ctm);
|
| - float extra=3.f*SkScalarCeilToScalar(xformedSigma-1/6.0f);
|
| - proxy_rect.outset(extra, extra);
|
| -
|
| - SkAutoTUnref<GrEffectRef> effect(GrRRectBlurEffect::Create(
|
| - context, xformedSigma, rrect));
|
| - if (!effect) {
|
| - return false;
|
| - }
|
| -
|
| - GrContext::AutoMatrix am;
|
| - if (!am.setIdentity(context, grp)) {
|
| - return false;
|
| - }
|
| -
|
| - grp->addCoverageEffect(effect);
|
| -
|
| - context->drawRect(*grp, proxy_rect);
|
| - return true;
|
| + return false;
|
| }
|
|
|
| bool SkBlurMaskFilterImpl::canFilterMaskGPU(const SkRect& srcBounds,
|
|
|