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, |