diff options
author | 2017-07-12 13:01:35 -0400 | |
---|---|---|
committer | 2017-07-12 20:36:38 +0000 | |
commit | d4b2c537d058ad4cb890ba116d00aa86c3416c08 (patch) | |
tree | 7c80a46e853448f5390df2b7d80dc5fe927ff557 /src/core/SkMaskBlurFilter.h | |
parent | 80a82dff82d11c229d33e87453e8510cbd1603b9 (diff) |
Experimental blur code with 32 bit fix.
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.
Bug: skia:
Change-Id: I847270906b0ceac1dfbf43ab5446756689ef660f
Reviewed-on: https://skia-review.googlesource.com/22700
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Herb Derby <herb@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 |