From a477154cfce6276277f4eacc20908a6c986c112c Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Mon, 10 Mar 2014 21:42:06 +0000 Subject: [PATCH] plumb API for analytic rrect blur BUG=skia:2281 R=bsalomon@google.com, reed@google.com Author: humper@google.com Review URL: https://codereview.chromium.org/189663012 git-svn-id: http://skia.googlecode.com/svn/trunk@13733 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/effects/SkBlurMask.cpp | 27 +++++++--------------- src/effects/SkBlurMask.h | 23 +++++------------- src/effects/SkBlurMaskFilter.cpp | 50 +++++++++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 42 deletions(-) diff --git a/src/effects/SkBlurMask.cpp b/src/effects/SkBlurMask.cpp index 50c16f4..9712ecc 100644 --- a/src/effects/SkBlurMask.cpp +++ b/src/effects/SkBlurMask.cpp @@ -475,14 +475,6 @@ void SkMask_FreeImage(uint8_t* image) { SkMask::FreeImage(image); } -bool SkBlurMask::Blur(SkMask* dst, const SkMask& src, - SkScalar radius, Style style, Quality quality, - SkIPoint* margin) { - return SkBlurMask::BoxBlur(dst, src, - SkBlurMask::ConvertRadiusToSigma(radius), - style, quality, margin); -} - bool SkBlurMask::BoxBlur(SkMask* dst, const SkMask& src, SkScalar sigma, Style style, Quality quality, SkIPoint* margin) { @@ -741,14 +733,6 @@ void SkBlurMask::ComputeBlurredScanline(uint8_t *pixels, const uint8_t *profile, } } -bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, - SkScalar radius, Style style, - SkIPoint *margin, SkMask::CreateMode createMode) { - return SkBlurMask::BlurRect(SkBlurMask::ConvertRadiusToSigma(radius), - dst, src, - style, margin, createMode); -} - bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, const SkRect &src, Style style, SkIPoint *margin, SkMask::CreateMode createMode) { @@ -850,10 +834,15 @@ bool SkBlurMask::BlurRect(SkScalar sigma, SkMask *dst, return true; } -bool SkBlurMask::BlurGroundTruth(SkMask* dst, const SkMask& src, SkScalar radius, - Style style, SkIPoint* margin) { - return BlurGroundTruth(ConvertRadiusToSigma(radius), dst, src, style, margin); +bool SkBlurMask::BlurRRect(SkScalar sigma, SkMask *dst, + const SkRRect &src, Style style, + SkIPoint *margin, SkMask::CreateMode createMode) { + // Temporary for now -- always fail, should cause caller to fall back + // to old path. Plumbing just to land API and parallelize effort. + + return false; } + // The "simple" blur is a direct implementation of separable convolution with a discrete // gaussian kernel. It's "ground truth" in a sense; too slow to be used, but very // useful for correctness comparisons. diff --git a/src/effects/SkBlurMask.h b/src/effects/SkBlurMask.h index 354fa84..eb67d4c 100644 --- a/src/effects/SkBlurMask.h +++ b/src/effects/SkBlurMask.h @@ -12,6 +12,7 @@ #include "SkShader.h" #include "SkMask.h" +#include "SkRRect.h" class SkBlurMask { public: @@ -34,6 +35,11 @@ public: SkIPoint *margin = NULL, SkMask::CreateMode createMode = SkMask::kComputeBoundsAndRenderImage_CreateMode); + static bool BlurRRect(SkScalar sigma, SkMask *dst, const SkRRect &src, + Style style, + SkIPoint *margin = NULL, + SkMask::CreateMode createMode = + SkMask::kComputeBoundsAndRenderImage_CreateMode); static bool BoxBlur(SkMask* dst, const SkMask& src, SkScalar sigma, Style style, Quality quality, SkIPoint* margin = NULL); @@ -44,23 +50,6 @@ public: Style style, SkIPoint* margin = NULL); - SK_ATTR_DEPRECATED("use sigma version") - static bool BlurRect(SkMask *dst, const SkRect &src, - SkScalar radius, Style style, - SkIPoint *margin = NULL, - SkMask::CreateMode createMode = - SkMask::kComputeBoundsAndRenderImage_CreateMode); - - SK_ATTR_DEPRECATED("use sigma version") - static bool Blur(SkMask* dst, const SkMask& src, - SkScalar radius, Style style, Quality quality, - SkIPoint* margin = NULL); - - SK_ATTR_DEPRECATED("use sigma version") - static bool BlurGroundTruth(SkMask* dst, const SkMask& src, - SkScalar radius, Style style, - SkIPoint* margin = NULL); - static SkScalar ConvertRadiusToSigma(SkScalar radius); /* Helper functions for analytic rectangle blurs */ diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index 5fc5ccc..2d7ff18 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -69,6 +69,8 @@ protected: bool filterRectMask(SkMask* dstM, const SkRect& r, const SkMatrix& matrix, SkIPoint* margin, SkMask::CreateMode createMode) const; + bool filterRRectMask(SkMask* dstM, const SkRRect& r, const SkMatrix& matrix, + SkIPoint* margin, SkMask::CreateMode createMode) const; private: // To avoid unseemly allocation requests (esp. for finite platforms like @@ -168,6 +170,15 @@ bool SkBlurMaskFilterImpl::filterRectMask(SkMask* dst, const SkRect& r, margin, createMode); } +bool SkBlurMaskFilterImpl::filterRRectMask(SkMask* dst, const SkRRect& r, + const SkMatrix& matrix, + SkIPoint* margin, SkMask::CreateMode createMode) const{ + SkScalar sigma = computeXformedSigma(matrix); + + return SkBlurMask::BlurRRect(sigma, dst, r, (SkBlurMask::Style)fBlurStyle, + margin, createMode); +} + #include "SkCanvas.h" static bool prepare_to_draw_into_mask(const SkRect& bounds, SkMask* mask) { @@ -244,6 +255,12 @@ static bool rect_exceeds(const SkRect& r, SkScalar v) { r.width() > v || r.height() > v; } +#ifdef SK_IGNORE_FAST_RRECT_BLUR +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.analyticRRect", true, "Use the faster analytic blur approach for ninepatch round rects" ); +#endif + SkMaskFilter::FilterReturn SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& matrix, const SkIRect& clipBounds, @@ -293,7 +310,19 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma srcM.fFormat = SkMask::kA8_Format; srcM.fRowBytes = 0; - if (!this->filterMask(&dstM, srcM, matrix, &margin)) { + bool filterResult = false; + if (c_analyticBlurRRect) { + // special case for fast round rect blur + // don't actually do the blur the first time, just compute the correct size + filterResult = this->filterRRectMask(&dstM, rrect, matrix, &margin, + SkMask::kJustComputeBounds_CreateMode); + } + + if (!filterResult) { + filterResult = this->filterMask(&dstM, srcM, matrix, &margin); + } + + if (!filterResult) { return kFalse_FilterReturn; } @@ -337,14 +366,23 @@ SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma radii[SkRRect::kLowerLeft_Corner] = LL; smallRR.setRectRadii(smallR, radii); - if (!draw_rrect_into_mask(smallRR, &srcM)) { - return kFalse_FilterReturn; + bool analyticBlurWorked = false; + if (c_analyticBlurRRect) { + analyticBlurWorked = + this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, + SkMask::kComputeBoundsAndRenderImage_CreateMode); } - SkAutoMaskFreeImage amf(srcM.fImage); + if (!analyticBlurWorked) { + if (!draw_rrect_into_mask(smallRR, &srcM)) { + return kFalse_FilterReturn; + } + + SkAutoMaskFreeImage amf(srcM.fImage); - if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { - return kFalse_FilterReturn; + if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { + return kFalse_FilterReturn; + } } patch->fMask.fBounds.offsetTo(0, 0); -- 2.7.4