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 { |