Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(584)

Side by Side Diff: src/core/SkBitmapFilter.h

Issue 1563183003: Refactor resize filter to go faster (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: make mitchell filter locals conform to skia style Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/core/SkBitmapFilter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2013 Google Inc. 2 * Copyright 2013 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #ifndef SkBitmapFilter_DEFINED 8 #ifndef SkBitmapFilter_DEFINED
9 #define SkBitmapFilter_DEFINED 9 #define SkBitmapFilter_DEFINED
10 10
11 #include "SkFixed.h" 11 #include "SkFixed.h"
12 #include "SkMath.h" 12 #include "SkMath.h"
13 #include "SkScalar.h" 13 #include "SkScalar.h"
14 14
15 #ifndef SK_SUPPORT_LEGACY_BITMAP_FILTER
16 #include "SkNx.h"
17 #endif
18
15 // size of the precomputed bitmap filter tables for high quality filtering. 19 // size of the precomputed bitmap filter tables for high quality filtering.
16 // Used to precompute the shape of the filter kernel. 20 // Used to precompute the shape of the filter kernel.
17 // Table size chosen from experiments to see where I could start to see a differ ence. 21 // Table size chosen from experiments to see where I could start to see a differ ence.
18 22
19 #define SKBITMAP_FILTER_TABLE_SIZE 128 23 #define SKBITMAP_FILTER_TABLE_SIZE 128
20 24
21 class SkBitmapFilter { 25 class SkBitmapFilter {
22 public: 26 public:
23 SkBitmapFilter(float width) 27 SkBitmapFilter(float width)
24 : fWidth(width), fInvWidth(1.f/width) { 28 : fWidth(width), fInvWidth(1.f/width) {
(...skipping 15 matching lines...) Expand all
40 precomputeTable(); 44 precomputeTable();
41 } 45 }
42 int filter_idx = int(sk_float_abs(x * fLookupMultiplier)); 46 int filter_idx = int(sk_float_abs(x * fLookupMultiplier));
43 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE); 47 SkASSERT(filter_idx < SKBITMAP_FILTER_TABLE_SIZE);
44 return fFilterTableScalar[filter_idx]; 48 return fFilterTableScalar[filter_idx];
45 } 49 }
46 50
47 float width() const { return fWidth; } 51 float width() const { return fWidth; }
48 float invWidth() const { return fInvWidth; } 52 float invWidth() const { return fInvWidth; }
49 virtual float evaluate(float x) const = 0; 53 virtual float evaluate(float x) const = 0;
54
55 #ifndef SK_SUPPORT_LEGACY_BITMAP_FILTER
56 virtual float evaluate_n(float val, float diff, int count, float* output) const {
57 float sum = 0;
58 for (int index = 0; index < count; index++) {
59 float filterValue = evaluate(val);
60 *output++ = filterValue;
61 sum += filterValue;
62 val += diff;
63 }
64 return sum;
65 }
66 #endif
67
50 virtual ~SkBitmapFilter() {} 68 virtual ~SkBitmapFilter() {}
51 69
52 static SkBitmapFilter* Allocate(); 70 static SkBitmapFilter* Allocate();
53 protected: 71 protected:
54 float fWidth; 72 float fWidth;
55 float fInvWidth; 73 float fInvWidth;
56 74
57 float fLookupMultiplier; 75 float fLookupMultiplier;
58 76
59 mutable bool fPrecomputed; 77 mutable bool fPrecomputed;
60 mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE]; 78 mutable SkFixed fFilterTable[SKBITMAP_FILTER_TABLE_SIZE];
61 mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE]; 79 mutable SkScalar fFilterTableScalar[SKBITMAP_FILTER_TABLE_SIZE];
62 private: 80 private:
63 void precomputeTable() const { 81 void precomputeTable() const {
64 fPrecomputed = true; 82 fPrecomputed = true;
65 SkFixed *ftp = fFilterTable; 83 SkFixed *ftp = fFilterTable;
66 SkScalar *ftpScalar = fFilterTableScalar; 84 SkScalar *ftpScalar = fFilterTableScalar;
67 for (int x = 0; x < SKBITMAP_FILTER_TABLE_SIZE; ++x) { 85 for (int x = 0; x < SKBITMAP_FILTER_TABLE_SIZE; ++x) {
68 float fx = ((float)x + .5f) * this->width() / SKBITMAP_FILTER_TABL E_SIZE; 86 float fx = ((float)x + .5f) * this->width() / SKBITMAP_FILTER_TABL E_SIZE;
69 float filter_value = evaluate(fx); 87 float filter_value = evaluate(fx);
70 *ftpScalar++ = filter_value; 88 *ftpScalar++ = filter_value;
71 *ftp++ = SkFloatToFixed(filter_value); 89 *ftp++ = SkFloatToFixed(filter_value);
72 } 90 }
73 } 91 }
74 }; 92 };
75 93
76 class SkMitchellFilter: public SkBitmapFilter { 94 class SkMitchellFilter : public SkBitmapFilter {
77 public: 95 public:
78 SkMitchellFilter(float b, float c, float width=2.0f) 96 #ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
79 : SkBitmapFilter(width), B(b), C(c) { 97 SkMitchellFilter()
98 : INHERITED(2), B(1.f / 3), C(1.f / 3) {
80 } 99 }
100 #else
101 SkMitchellFilter()
102 : INHERITED(2)
103 , fB(1.f / 3.f)
104 , fC(1.f / 3.f)
105 , fA1(-fB - 6*fC)
106 , fB1(6*fB + 30*fC)
107 , fC1(-12*fB - 48*fC)
108 , fD1(8*fB + 24*fC)
109 , fA2(12 - 9*fB - 6*fC)
110 , fB2(-18 + 12*fB + 6*fC)
111 , fD2(6 - 2*fB) {
112 }
113 #endif
81 114
82 float evaluate(float x) const override { 115 float evaluate(float x) const override {
83 x = fabsf(x); 116 x = fabsf(x);
84 if (x > 2.f) { 117 if (x > 2.f) {
85 return 0; 118 return 0;
86 } else if (x > 1.f) { 119 } else if (x > 1.f) {
120 #ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
87 return ((-B - 6*C) * x*x*x + (6*B + 30*C) * x*x + 121 return ((-B - 6*C) * x*x*x + (6*B + 30*C) * x*x +
88 (-12*B - 48*C) * x + (8*B + 24*C)) * (1.f/6.f); 122 (-12*B - 48*C) * x + (8*B + 24*C)) * (1.f/6.f);
123 #else
124 return (((fA1 * x + fB1) * x + fC1) * x + fD1) * (1.f/6.f);
125 #endif
89 } else { 126 } else {
127 #ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
90 return ((12 - 9*B - 6*C) * x*x*x + 128 return ((12 - 9*B - 6*C) * x*x*x +
91 (-18 + 12*B + 6*C) * x*x + 129 (-18 + 12*B + 6*C) * x*x +
92 (6 - 2*B)) * (1.f/6.f); 130 (6 - 2*B)) * (1.f/6.f);
131 #else
132 return ((fA2 * x + fB2) * x*x + fD2) * (1.f/6.f);
133 #endif
93 } 134 }
94 } 135 }
136
137 #ifndef SK_SUPPORT_LEGACY_BITMAP_FILTER
138 // TODO : native Sk4f abs
139 static Sk4f abs(const Sk4f& x) {
140 Sk4f neg = x < Sk4f(0);
141 return neg.thenElse(Sk4f(0) - x, x);
142 }
143
144 Sk4f evalcore_n(const Sk4f& val) const {
145 Sk4f x = abs(val);
146 Sk4f over2 = x > Sk4f(2);
147 Sk4f over1 = x > Sk4f(1);
148 Sk4f poly1 = (((Sk4f(fA1) * x + Sk4f(fB1)) * x + Sk4f(fC1)) * x + Sk4f (fD1))
149 * Sk4f(1.f/6.f);
150 Sk4f poly0 = ((Sk4f(fA2) * x + Sk4f(fB2)) * x*x + Sk4f(fD2)) * Sk4f(1. f/6.f);
151 return over2.thenElse(Sk4f(0), over1.thenElse(poly1, poly0));
152 }
153
154 float evaluate_n(float val, float diff, int count, float* output) const ov erride {
155 Sk4f sum(0);
156 while (count >= 4) {
157 float v0 = val;
158 float v1 = val += diff;
159 float v2 = val += diff;
160 float v3 = val += diff;
161 val += diff;
162 Sk4f filterValue = evalcore_n(Sk4f(v0, v1, v2, v3));
163 filterValue.store(output);
164 output += 4;
165 sum = sum + filterValue;
166 count -= 4;
167 }
168 float sums[4];
169 sum.store(sums);
170 float result = sums[0] + sums[1] + sums[2] + sums[3];
171 result += INHERITED::evaluate_n(val, diff, count, output);
172 return result;
173 }
174 #endif
175
95 protected: 176 protected:
177 #ifdef SK_SUPPORT_LEGACY_BITMAP_FILTER
96 float B, C; 178 float B, C;
179 #else
180 float fB, fC;
181 float fA1, fB1, fC1, fD1;
182 float fA2, fB2, fD2;
183 #endif
184 private:
185 typedef SkBitmapFilter INHERITED;
97 }; 186 };
98 187
99 class SkGaussianFilter: public SkBitmapFilter { 188 class SkGaussianFilter: public SkBitmapFilter {
100 public: 189 public:
101 SkGaussianFilter(float a, float width=2.0f) 190 SkGaussianFilter(float a, float width=2.0f)
102 : SkBitmapFilter(width), alpha(a), expWidth(expf(-alpha * width * width)) { 191 : SkBitmapFilter(width), alpha(a), expWidth(expf(-alpha * width * width)) {
103 } 192 }
104 193
105 float evaluate(float x) const override { 194 float evaluate(float x) const override {
106 return SkTMax(0.f, float(expf(-alpha*x*x) - expWidth)); 195 return SkTMax(0.f, float(expf(-alpha*x*x) - expWidth));
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 return 1.0f; // Special case the discontinuity at the origin. 255 return 1.0f; // Special case the discontinuity at the origin.
167 } 256 }
168 float xpi = x * static_cast<float>(SK_ScalarPI); 257 float xpi = x * static_cast<float>(SK_ScalarPI);
169 return (sk_float_sin(xpi) / xpi) * // sinc(x) 258 return (sk_float_sin(xpi) / xpi) * // sinc(x)
170 sk_float_sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/fWidth ) 259 sk_float_sin(xpi / fWidth) / (xpi / fWidth); // sinc(x/fWidth )
171 } 260 }
172 }; 261 };
173 262
174 263
175 #endif 264 #endif
OLDNEW
« no previous file with comments | « no previous file | src/core/SkBitmapFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698