Revert of Fast path for blurred round rects -- blur a small 9patch rect on the CPU...
authorcommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 28 Apr 2014 14:44:54 +0000 (14:44 +0000)
committercommit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 28 Apr 2014 14:44:54 +0000 (14:44 +0000)
Reason for revert:
Looks like this causes unit tests to fail with a zero constructor like this one: http://108.170.220.120:10117/builders/Test-Win7-ShuttleA-HD2000-x86-Release/builds/2326/steps/RunTests/logs/stdio

Original issue's description:
> Fast path for blurred round rects -- blur a small 9patch rect on the CPU
> And nonlinearly stretch the resulting texture across proxy geometry.
>
> BUG=
>
> Committed: http://code.google.com/p/skia/source/detail?r=14392

R=bsalomon@google.com, reed@google.com, humper@google.com
TBR=bsalomon@google.com, humper@google.com, reed@google.com
NOTREECHECKS=true
NOTRY=true
BUG=

Author: caryclark@google.com

Review URL: https://codereview.chromium.org/258893010

git-svn-id: http://skia.googlecode.com/svn/trunk@14400 2bbb7eff-a529-9590-31e7-b0007b416f81

expectations/gm/ignored-tests.txt
gm/blurroundrect.cpp
src/effects/SkBlurMask.cpp
src/effects/SkBlurMask.h
src/effects/SkBlurMaskFilter.cpp
src/images/SkImageDecoder_libwebp.cpp

index 4e5eb97726f7eed8706526f4f56490346dadc789..51f2c8bb5f2523013eef9c53ee1441f83edcb81f 100644 (file)
@@ -57,6 +57,3 @@ aaclip
 composeshader
 peekpixels
 
-# humper: https://codereview.chromium.org/248613004/
-# Changed the test in a few ways, will need rebaselining.
-simpleblurrrect
index 08086aca916a4803d7cbf522898697cc37d0a428..f688380f0e0253e6b96d6ca406c5fcd150d89c6d 100644 (file)
@@ -106,32 +106,30 @@ protected:
     }
 
     virtual SkISize onISize() SK_OVERRIDE {
-        return SkISize::Make(950, 950);
+        return SkISize::Make(750, 750);
     }
 
     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
         canvas->scale(1.5f, 1.5f);
-        canvas->translate(50,50);
 
-        const float blurRadii[] = { 1,5,10,20 };
-        const int cornerRadii[] = { 1,5,10,20 };
+        const int blurRadii[] = { 1, 3, 6, 10 };
+        const int cornerRadii[] = { 1, 3, 6, 10 };
         const SkRect r = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
         for (size_t i = 0; i < SK_ARRAY_COUNT(blurRadii); ++i) {
             SkAutoCanvasRestore autoRestore(canvas, true);
-            canvas->translate(0, (r.height() + SkIntToScalar(50)) * i);
+            canvas->translate(0, (r.height() + SkIntToScalar(20)) * i);
             for (size_t j = 0; j < SK_ARRAY_COUNT(cornerRadii); ++j) {
                 SkMaskFilter* filter = SkBlurMaskFilter::Create(
                     SkBlurMaskFilter::kNormal_BlurStyle,
-                    SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(blurRadii[i])),
-                    SkBlurMaskFilter::kHighQuality_BlurFlag);
+                    SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(blurRadii[i])));
                 SkPaint paint;
-                paint.setColor(SK_ColorBLACK);
+                paint.setColor(SK_ColorBLUE);
                 paint.setMaskFilter(filter)->unref();
 
                 SkRRect rrect;
                 rrect.setRectXY(r, SkIntToScalar(cornerRadii[j]), SkIntToScalar(cornerRadii[j]));
                 canvas->drawRRect(rrect, paint);
-                canvas->translate(r.width() + SkIntToScalar(50), 0);
+                canvas->translate(r.width() + SkIntToScalar(10), 0);
             }
         }
     }
index f33817adee0830bf2fea88c82b681f9cb544b086..9712ecc4757162fd05a966c5dbf3bffd54e50fb1 100644 (file)
@@ -477,14 +477,14 @@ void SkMask_FreeImage(uint8_t* image) {
 
 bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src,
                          SkScalar sigma, Style style, Quality quality,
-                         SkIPoint* margin, bool force_quality) {
+                         SkIPoint* margin) {
 
     if (src.fFormat != SkMask::kA8_Format) {
         return false;
     }
 
     // Force high quality off for small radii (performance)
-    if (!force_quality && sigma <= SkIntToScalar(2)) {
+    if (sigma <= SkIntToScalar(2)) {
         quality = kLow_Quality;
     }
 
index d4cd3d1ea31c6c16233aed889accc54278186f65..eb67d4c9f8b04f9443123c9f3c10b3a9a9a39567 100644 (file)
@@ -40,16 +40,9 @@ public:
                          SkIPoint *margin = NULL,
                          SkMask::CreateMode createMode =
                                                 SkMask::kComputeBoundsAndRenderImage_CreateMode);
-
-    // forceQuality will prevent BoxBlur from falling back to the low quality approach when sigma
-    // is very small -- this can be used predict the margin bump ahead of time without completely
-    // replicating the internal logic.  This permits not only simpler caching of blurred results,
-    // but also being able to predict precisely at what pixels the blurred profile of e.g. a
-    // rectangle will lie.
-
     static bool BoxBlur(SkMask* dst, const SkMask& src,
                         SkScalar sigma, Style style, Quality quality,
-                        SkIPoint* margin = NULL, bool forceQuality = false);
+                        SkIPoint* margin = NULL);
 
     // the "ground truth" blur does a gaussian convolution; it's slow
     // but useful for comparison purposes.
index 4bc48ab7414bbb94c709be5775bf0a9f01da700b..ff98daf048181bec780ebfd6df271fc53b807c0e 100644 (file)
@@ -25,7 +25,6 @@
 #include "effects/GrSimpleTextureEffect.h"
 #include "GrTBackendEffectFactory.h"
 #include "SkGrPixelRef.h"
-#include "SkDraw.h"
 #endif
 
 class SkBlurMaskFilterImpl : public SkMaskFilter {
@@ -261,9 +260,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
@@ -820,285 +819,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, &params);
-
-    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, SkBlurMask::kNormal_Style, SkBlurMask::kHigh_Quality, NULL, true );
-
-        blurNinePatchTexture = context->createTexture(&params, 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(20.f, 1000.f);
-    SkScalar h = random->nextRangeScalar(20.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 != SkBlurMaskFilter::kNormal_BlurStyle) {
-        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,
index 02990258ebe84dbce0f46c5436a95b24b8bfe8b2..4e23e50f5760fcf2024799265d7b4257823cf071 100644 (file)
@@ -559,6 +559,15 @@ static void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
   }
 }
 
+static void Alpha8_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
+                          const SkPMColor* SK_RESTRICT ctable) {
+  const uint8_t* SK_RESTRICT src = (const uint8_t*)in;
+  for (int i = 0; i < width; ++i) {
+      rgb[0] = rgb[1] = rgb[2] = *src++;
+      rgb += 3;
+  }
+}
+
 static ScanlineImporter ChooseImporter(const SkBitmap::Config& config,
                                        bool  hasAlpha,
                                        int*  bpp) {
@@ -585,6 +594,9 @@ static ScanlineImporter ChooseImporter(const SkBitmap::Config& config,
         case SkBitmap::kIndex8_Config:
             *bpp = 3;
             return Index8_To_RGB;
+        case SkBitmap::kA8_Config:
+            *bpp = 3;
+            return Alpha8_To_RGB;
         default:
             return NULL;
     }