diff options
author | Herb Derby <herb@google.com> | 2017-07-11 16:05:37 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-07-12 02:40:36 +0000 |
commit | d96ed9d0def2d660f537e4ab5c79e9e66470ee22 (patch) | |
tree | 066be6816a9c9bd66faadd5492623d777bf9117e /src/core/SkMaskBlurFilter.h | |
parent | 52e4fd98b5c6b296e4598f3243a891bc76715590 (diff) |
Experimental blur code.
This uses a new method of blurring that runs the three
passes of the box filter in a single pass. This implementation
currently only does 1x1 pixel at a time, but it should be simple
to expand to 4x4 pixels at a time.
On the blur_10_normal_high_quality benchmark, the new is 7% faster
than the old code. For the blur_100.50_normal_high_quality
benchmark, the new code is 11% slower.
Change-Id: Iea37294abc7c27de5ad569adf8bc62df77eafd02
Reviewed-on: https://skia-review.googlesource.com/21739
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Reed <reed@google.com>
Diffstat (limited to 'src/core/SkMaskBlurFilter.h')
-rw-r--r-- | src/core/SkMaskBlurFilter.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/core/SkMaskBlurFilter.h b/src/core/SkMaskBlurFilter.h new file mode 100644 index 0000000000..9becadca39 --- /dev/null +++ b/src/core/SkMaskBlurFilter.h @@ -0,0 +1,67 @@ +/* + * Copyright 2017 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBlurMaskFilter_DEFINED +#define SkBlurMaskFilter_DEFINED + +#include <algorithm> +#include <memory> + +#include "SkMask.h" +#include "SkTypes.h" + +// Implement a single channel Gaussian blur. The specifics for implementation are taken from: +// https://drafts.fxtf.org/filters/#feGaussianBlurElement +class SkMaskBlurFilter { +public: + // Given a filter specified by sigma, generate various quantities. + class FilterInfo { + public: + explicit FilterInfo(double sigma); + + // The final weight to divide by given a box size calculated from sigma accumulated for + // all three passes. For example, if the box size is 5, then the final weight for all + // three passes is 5^3 or 125. + uint64_t weight() const; + + // The distance between the first value of the dst and the first value of the src. + uint32_t borderSize() const; + + // The size of the box filter. + size_t diameter(uint8_t) const; + + // A factor used to simulate division using multiplication and shift. + uint64_t scaledWeight() const; + + private: + const uint32_t fFilterWindow; + const uint64_t fScaledWeight; + }; + + // Create an object suitable for filtering an SkMask using a filter with width sigmaW and + // height sigmaH. + SkMaskBlurFilter(double sigmaW, double sigmaH); + + // Given a src SkMask, generate dst SkMask returning the border width and height. + SkIPoint blur(const SkMask& src, SkMask* dst) const; + +private: + size_t bufferSize(uint8_t bufferPass) const; + + void blurOneScan(FilterInfo gen, + const uint8_t* src, size_t srcStride, const uint8_t* srcEnd, + uint8_t* dst, size_t dstStride, uint8_t* dstEnd) const; + + + const FilterInfo fInfoW, + fInfoH; + std::unique_ptr<uint32_t[]> fBuffer0, + fBuffer1, + fBuffer2; +}; + +#endif // SkBlurMaskFilter_DEFINED |