| Index: src/core/SkBitmapFilter.h
|
| diff --git a/src/core/SkBitmapFilter.h b/src/core/SkBitmapFilter.h
|
| index eb327d716c7082748a1eb6abf3ccd3a543070aa6..038ee98eae6fa63ec8737847301ff881eed71f47 100644
|
| --- a/src/core/SkBitmapFilter.h
|
| +++ b/src/core/SkBitmapFilter.h
|
| @@ -12,6 +12,10 @@
|
| #include "SkMath.h"
|
| #include "SkScalar.h"
|
|
|
| +#ifndef SK_SUPPORT_LEGACY_BITMAP_FILTER
|
| +#include "SkNx.h"
|
| +#endif
|
| +
|
| // size of the precomputed bitmap filter tables for high quality filtering.
|
| // Used to precompute the shape of the filter kernel.
|
| // Table size chosen from experiments to see where I could start to see a difference.
|
| @@ -47,6 +51,20 @@ class SkBitmapFilter {
|
| float width() const { return fWidth; }
|
| float invWidth() const { return fInvWidth; }
|
| virtual float evaluate(float x) const = 0;
|
| +
|
| +#ifndef SK_SUPPORT_LEGACY_BITMAP_FILTER
|
| + virtual float evaluate_n(float val, float diff, int count, float* output) const {
|
| + float sum = 0;
|
| + for (int index = 0; index < count; index++) {
|
| + float filterValue = evaluate(val);
|
| + *output++ = filterValue;
|
| + sum += filterValue;
|
| + val += diff;
|
| + }
|
| + return sum;
|
| + }
|
| +#endif
|
| +
|
| virtual ~SkBitmapFilter() {}
|
|
|
| static SkBitmapFilter* Allocate();
|
| @@ -73,27 +91,98 @@ class SkBitmapFilter {
|
| }
|
| };
|
|
|
| -class SkMitchellFilter: public SkBitmapFilter {
|
| +class SkMitchellFilter : public SkBitmapFilter {
|
| public:
|
| - SkMitchellFilter(float b, float c, float width=2.0f)
|
| - : SkBitmapFilter(width), B(b), C(c) {
|
| +#ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
|
| + SkMitchellFilter()
|
| + : INHERITED(2), B(1.f / 3), C(1.f / 3) {
|
| + }
|
| +#else
|
| + SkMitchellFilter()
|
| + : INHERITED(2)
|
| + , fB(1.f / 3.f)
|
| + , fC(1.f / 3.f)
|
| + , fA1(-fB - 6*fC)
|
| + , fB1(6*fB + 30*fC)
|
| + , fC1(-12*fB - 48*fC)
|
| + , fD1(8*fB + 24*fC)
|
| + , fA2(12 - 9*fB - 6*fC)
|
| + , fB2(-18 + 12*fB + 6*fC)
|
| + , fD2(6 - 2*fB) {
|
| }
|
| +#endif
|
|
|
| float evaluate(float x) const override {
|
| x = fabsf(x);
|
| if (x > 2.f) {
|
| return 0;
|
| } else if (x > 1.f) {
|
| +#ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
|
| return ((-B - 6*C) * x*x*x + (6*B + 30*C) * x*x +
|
| (-12*B - 48*C) * x + (8*B + 24*C)) * (1.f/6.f);
|
| +#else
|
| + return (((fA1 * x + fB1) * x + fC1) * x + fD1) * (1.f/6.f);
|
| +#endif
|
| } else {
|
| +#ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
|
| return ((12 - 9*B - 6*C) * x*x*x +
|
| (-18 + 12*B + 6*C) * x*x +
|
| (6 - 2*B)) * (1.f/6.f);
|
| +#else
|
| + return ((fA2 * x + fB2) * x*x + fD2) * (1.f/6.f);
|
| +#endif
|
| }
|
| }
|
| +
|
| +#ifndef SK_SUPPORT_LEGACY_BITMAP_FILTER
|
| + // TODO : native Sk4f abs
|
| + static Sk4f abs(const Sk4f& x) {
|
| + Sk4f neg = x < Sk4f(0);
|
| + return neg.thenElse(Sk4f(0) - x, x);
|
| + }
|
| +
|
| + Sk4f evalcore_n(const Sk4f& val) const {
|
| + Sk4f x = abs(val);
|
| + Sk4f over2 = x > Sk4f(2);
|
| + Sk4f over1 = x > Sk4f(1);
|
| + Sk4f poly1 = (((Sk4f(fA1) * x + Sk4f(fB1)) * x + Sk4f(fC1)) * x + Sk4f(fD1))
|
| + * Sk4f(1.f/6.f);
|
| + Sk4f poly0 = ((Sk4f(fA2) * x + Sk4f(fB2)) * x*x + Sk4f(fD2)) * Sk4f(1.f/6.f);
|
| + return over2.thenElse(Sk4f(0), over1.thenElse(poly1, poly0));
|
| + }
|
| +
|
| + float evaluate_n(float val, float diff, int count, float* output) const override {
|
| + Sk4f sum(0);
|
| + while (count >= 4) {
|
| + float v0 = val;
|
| + float v1 = val += diff;
|
| + float v2 = val += diff;
|
| + float v3 = val += diff;
|
| + val += diff;
|
| + Sk4f filterValue = evalcore_n(Sk4f(v0, v1, v2, v3));
|
| + filterValue.store(output);
|
| + output += 4;
|
| + sum = sum + filterValue;
|
| + count -= 4;
|
| + }
|
| + float sums[4];
|
| + sum.store(sums);
|
| + float result = sums[0] + sums[1] + sums[2] + sums[3];
|
| + result += INHERITED::evaluate_n(val, diff, count, output);
|
| + return result;
|
| + }
|
| +#endif
|
| +
|
| protected:
|
| +#ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
|
| float B, C;
|
| +#else
|
| + float fB, fC;
|
| + float fA1, fB1, fC1, fD1;
|
| + float fA2, fB2, fD2;
|
| +#endif
|
| + private:
|
| + typedef SkBitmapFilter INHERITED;
|
| };
|
|
|
| class SkGaussianFilter: public SkBitmapFilter {
|
|
|