aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2016-01-14 10:10:56 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-01-14 10:10:56 -0800
commita36c710bf56b2123ab25b59aa177191229325698 (patch)
treefc519a8eb083211f428de0e6838df7472a639bfe
parentde83b41cc7fc5bd1398e06c011e698215261665f (diff)
add explicit bench for raw bitmapscaler
-rw-r--r--bench/BitmapScaleBench.cpp48
-rw-r--r--src/core/SkBitmapFilter.h352
2 files changed, 219 insertions, 181 deletions
diff --git a/bench/BitmapScaleBench.cpp b/bench/BitmapScaleBench.cpp
index 37ce7cf65a..2e8f72e03c 100644
--- a/bench/BitmapScaleBench.cpp
+++ b/bench/BitmapScaleBench.cpp
@@ -110,3 +110,51 @@ DEF_BENCH(return new BitmapFilterScaleBench(90, 30);)
DEF_BENCH(return new BitmapFilterScaleBench(90, 10);)
DEF_BENCH(return new BitmapFilterScaleBench(256, 64);)
DEF_BENCH(return new BitmapFilterScaleBench(64, 256);)
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkBitmapScaler.h"
+
+class PixmapScalerBench: public Benchmark {
+ SkBitmapScaler::ResizeMethod fMethod;
+ SkString fName;
+ SkBitmap fSrc, fDst;
+
+public:
+ PixmapScalerBench(SkBitmapScaler::ResizeMethod method, const char suffix[]) : fMethod(method) {
+ fName.printf("pixmapscaler_%s", suffix);
+ }
+
+protected:
+ const char* onGetName() override {
+ return fName.c_str();
+ }
+
+ SkIPoint onGetSize() override { return{ 100, 100 }; }
+
+ bool isSuitableFor(Backend backend) override {
+ return backend == kNonRendering_Backend;
+ }
+
+ void onDelayedSetup() override {
+ fSrc.allocN32Pixels(640, 480);
+ fDst.allocN32Pixels(300, 250);
+ }
+
+ void onDraw(int loops, SkCanvas*) override {
+ SkPixmap src, dst;
+ fSrc.peekPixels(&src);
+ fDst.peekPixels(&dst);
+ for (int i = 0; i < loops * 16; i++) {
+ SkBitmapScaler::Resize(dst, src, fMethod);
+ }
+ }
+
+private:
+ typedef Benchmark INHERITED;
+};
+DEF_BENCH( return new PixmapScalerBench(SkBitmapScaler::RESIZE_LANCZOS3, "lanczos"); )
+DEF_BENCH( return new PixmapScalerBench(SkBitmapScaler::RESIZE_MITCHELL, "mitchell"); )
+DEF_BENCH( return new PixmapScalerBench(SkBitmapScaler::RESIZE_HAMMING, "hamming"); )
+DEF_BENCH( return new PixmapScalerBench(SkBitmapScaler::RESIZE_TRIANGLE, "triangle"); )
+DEF_BENCH( return new PixmapScalerBench(SkBitmapScaler::RESIZE_BOX, "box"); )
diff --git a/src/core/SkBitmapFilter.h b/src/core/SkBitmapFilter.h
index 038ee98eae..c51a5390aa 100644
--- a/src/core/SkBitmapFilter.h
+++ b/src/core/SkBitmapFilter.h
@@ -23,154 +23,151 @@
#define SKBITMAP_FILTER_TABLE_SIZE 128
class SkBitmapFilter {
- public:
- SkBitmapFilter(float width)
- : fWidth(width), fInvWidth(1.f/width) {
- fPrecomputed = false;
- fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1);
- }
-
- SkFixed lookup(float x) const {
- if (!fPrecomputed) {
- precomputeTable();
- }
- int filter_idx = int(sk_float_abs(x * fLookupMultiplier));
- SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE);
- return fFilterTable[filter_idx];
- }
-
- SkScalar lookupScalar(float x) const {
- if (!fPrecomputed) {
- precomputeTable();
- }
- int filter_idx = int(sk_float_abs(x * fLookupMultiplier));
- SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE);
- return fFilterTableScalar[filter_idx];
- }
-
- float width() const { return fWidth; }
- float invWidth() const { return fInvWidth; }
- virtual float evaluate(float x) const = 0;
+public:
+ SkBitmapFilter(float width) : fWidth(width), fInvWidth(1.f/width) {
+ fPrecomputed = false;
+ fLookupMultiplier = this->invWidth() * (SKBITMAP_FILTER_TABLE_SIZE-1);
+ }
+ virtual ~SkBitmapFilter() {}
+
+ SkFixed lookup(float x) const {
+ if (!fPrecomputed) {
+ precomputeTable();
+ }
+ int filter_idx = int(sk_float_abs(x * fLookupMultiplier));
+ SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE);
+ return fFilterTable[filter_idx];
+ }
+
+ SkScalar lookupScalar(float x) const {
+ if (!fPrecomputed) {
+ precomputeTable();
+ }
+ int filter_idx = int(sk_float_abs(x * fLookupMultiplier));
+ SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE);
+ return fFilterTableScalar[filter_idx];
+ }
+
+ 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;
- }
+ 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();
- protected:
- float fWidth;
- float fInvWidth;
-
- float fLookupMultiplier;
-
- mutable bool fPrecomputed;
- mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE];
- mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE];
- private:
- void precomputeTable() const {
- fPrecomputed = true;
- SkFixed *ftp = fFilterTable;
- SkScalar *ftpScalar = fFilterTableScalar;
- for (int x = 0; x < SKBITMAP_FILTER_TABLE_SIZE; ++x) {
- float fx = ((float)x + .5f) * this->width() / SKBITMAP_FILTER_TABLE_SIZE;
- float filter_value = evaluate(fx);
- *ftpScalar++ = filter_value;
- *ftp++ = SkFloatToFixed(filter_value);
- }
- }
+ static SkBitmapFilter* Allocate();
+
+protected:
+ float fWidth;
+ float fInvWidth;
+ float fLookupMultiplier;
+
+ mutable bool fPrecomputed;
+ mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE];
+ mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE];
+
+private:
+ void precomputeTable() const {
+ fPrecomputed = true;
+ SkFixed *ftp = fFilterTable;
+ SkScalar *ftpScalar = fFilterTableScalar;
+ for (int x = 0; x < SKBITMAP_FILTER_TABLE_SIZE; ++x) {
+ float fx = ((float)x + .5f) * this->width() / SKBITMAP_FILTER_TABLE_SIZE;
+ float filter_value = evaluate(fx);
+ *ftpScalar++ = filter_value;
+ *ftp++ = SkFloatToFixed(filter_value);
+ }
+ }
};
-class SkMitchellFilter : public SkBitmapFilter {
- public:
+class SkMitchellFilter final : public SkBitmapFilter {
+public:
#ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
- SkMitchellFilter()
- : INHERITED(2), B(1.f / 3), C(1.f / 3) {
- }
+ 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) {
- }
+ 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) {
+ 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);
+ 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);
+ return (((fA1 * x + fB1) * x + fC1) * x + fD1) * (1.f/6.f);
#endif
- } else {
+ } 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);
+ 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);
+ 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;
- }
+ // 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:
@@ -181,52 +178,47 @@ class SkMitchellFilter : public SkBitmapFilter {
float fA1, fB1, fC1, fD1;
float fA2, fB2, fD2;
#endif
- private:
- typedef SkBitmapFilter INHERITED;
+private:
+ typedef SkBitmapFilter INHERITED;
};
-class SkGaussianFilter: public SkBitmapFilter {
- public:
- SkGaussianFilter(float a, float width=2.0f)
- : SkBitmapFilter(width), alpha(a), expWidth(expf(-alpha * width * width)) {
- }
+class SkGaussianFilter final : public SkBitmapFilter {
+ float fAlpha, fExpWidth;
- float evaluate(float x) const override {
- return SkTMax(0.f, float(expf(-alpha*x*x) - expWidth));
- }
- protected:
- float alpha, expWidth;
+public:
+ SkGaussianFilter(float a, float width = 2)
+ : SkBitmapFilter(width)
+ , fAlpha(a)
+ , fExpWidth(expf(-a * width * width))
+ {}
+
+ float evaluate(float x) const override {
+ return SkTMax(0.f, float(expf(-fAlpha*x*x) - fExpWidth));
+ }
};
-class SkTriangleFilter: public SkBitmapFilter {
- public:
- SkTriangleFilter(float width=1)
- : SkBitmapFilter(width) {
- }
+class SkTriangleFilter final : public SkBitmapFilter {
+public:
+ SkTriangleFilter(float width = 1) : SkBitmapFilter(width) {}
- float evaluate(float x) const override {
- return SkTMax(0.f, fWidth - fabsf(x));
- }
- protected:
+ float evaluate(float x) const override {
+ return SkTMax(0.f, fWidth - fabsf(x));
+ }
};
-class SkBoxFilter: public SkBitmapFilter {
- public:
- SkBoxFilter(float width=0.5f)
- : SkBitmapFilter(width) {
- }
+class SkBoxFilter final : public SkBitmapFilter {
+public:
+ SkBoxFilter(float width = 0.5f) : SkBitmapFilter(width) {}
- float evaluate(float x) const override {
- return (x >= -fWidth && x < fWidth) ? 1.0f : 0.0f;
- }
- protected:
+ float evaluate(float x) const override {
+ return (x >= -fWidth && x < fWidth) ? 1.0f : 0.0f;
+ }
};
-class SkHammingFilter: public SkBitmapFilter {
+class SkHammingFilter final : public SkBitmapFilter {
public:
- SkHammingFilter(float width=1.f)
- : SkBitmapFilter(width) {
- }
+ SkHammingFilter(float width = 1) : SkBitmapFilter(width) {}
+
float evaluate(float x) const override {
if (x <= -fWidth || x >= fWidth) {
return 0.0f; // Outside of the window.
@@ -241,23 +233,21 @@ public:
}
};
-class SkLanczosFilter: public SkBitmapFilter {
- public:
- SkLanczosFilter(float width=3.f)
- : SkBitmapFilter(width) {
- }
-
- float evaluate(float x) const override {
- if (x <= -fWidth || x >= fWidth) {
- return 0.0f; // Outside of the window.
- }
- if (x > -FLT_EPSILON && x < FLT_EPSILON) {
- return 1.0f; // Special case the discontinuity at the origin.
- }
- float xpi = x * static_cast<float>(SK_ScalarPI);
- return (sk_float_sin(xpi) / xpi) * // sinc(x)
- sk_float_sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/fWidth)
- }
+class SkLanczosFilter final : public SkBitmapFilter {
+public:
+ SkLanczosFilter(float width = 3.f) : SkBitmapFilter(width) {}
+
+ float evaluate(float x) const override {
+ if (x <= -fWidth || x >= fWidth) {
+ return 0.0f; // Outside of the window.
+ }
+ if (x > -FLT_EPSILON && x < FLT_EPSILON) {
+ return 1.0f; // Special case the discontinuity at the origin.
+ }
+ float xpi = x * static_cast<float>(SK_ScalarPI);
+ return (sk_float_sin(xpi) / xpi) * // sinc(x)
+ sk_float_sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/fWidth)
+ }
};