]> git.sesse.net Git - movit/blob - resample_effect_test.cpp
84f61e78e16381bd70174c4fc470dfcc29591ccf
[movit] / resample_effect_test.cpp
1 // Unit tests for ResampleEffect.
2
3 #include <epoxy/gl.h>
4 #include <gtest/gtest.h>
5 #include <math.h>
6
7 #include <memory>
8
9 #include "effect_chain.h"
10 #include "flat_input.h"
11 #include "fp16.h"
12 #include "image_format.h"
13 #include "init.h"
14 #include "resample_effect.h"
15 #include "test_util.h"
16
17 using namespace std;
18
19 namespace movit {
20
21 namespace {
22
23 float sinc(float x)
24 {
25         return sin(M_PI * x) / (M_PI * x);
26 }
27
28 float lanczos(float x, float a)
29 {
30         if (fabs(x) >= a) {
31                 return 0.0f;
32         } else {
33                 return sinc(x) * sinc(x / a);
34         }
35 }
36
37 }  // namespace
38
39 TEST(ResampleEffectTest, IdentityTransformDoesNothing) {
40         const int size = 4;
41
42         float data[size * size] = {
43                 0.0, 1.0, 0.0, 1.0,
44                 0.0, 1.0, 1.0, 0.0,
45                 0.0, 0.5, 1.0, 0.5,
46                 0.0, 0.0, 0.0, 0.0,
47         };
48         float out_data[size * size];
49
50         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
51         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
52         ASSERT_TRUE(resample_effect->set_int("width", 4));
53         ASSERT_TRUE(resample_effect->set_int("height", 4));
54         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
55
56         expect_equal(data, out_data, size, size);
57 }
58
59 TEST(ResampleEffectTest, UpscaleByTwoGetsCorrectPixelCenters) {
60         const int size = 5;
61
62         float data[size * size] = {
63                 0.0, 0.0, 0.0, 0.0, 0.0,
64                 0.0, 0.0, 0.0, 0.0, 0.0,
65                 0.0, 0.0, 1.0, 0.0, 0.0,
66                 0.0, 0.0, 0.0, 0.0, 0.0,
67                 0.0, 0.0, 0.0, 0.0, 0.0,
68         };
69         float expected_data[size * size * 4], out_data[size * size * 4];
70
71         for (int y = 0; y < size * 2; ++y) {
72                 for (int x = 0; x < size * 2; ++x) {
73                         float weight = lanczos((x - size + 0.5f) * 0.5f, 3.0f);
74                         weight *= lanczos((y - size + 0.5f) * 0.5f, 3.0f);
75                         expected_data[y * (size * 2) + x] = weight;
76                 }
77         }
78
79         EffectChainTester tester(nullptr, size * 2, size * 2, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
80
81         ImageFormat format;
82         format.color_space = COLORSPACE_sRGB;
83         format.gamma_curve = GAMMA_LINEAR;
84
85         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size, size);
86         input->set_pixel_data(data);
87         tester.get_chain()->add_input(input);
88
89         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
90         ASSERT_TRUE(resample_effect->set_int("width", size * 2));
91         ASSERT_TRUE(resample_effect->set_int("height", size * 2));
92         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
93
94         expect_equal(expected_data, out_data, size * 2, size * 2);
95 }
96
97 TEST(ResampleEffectTest, DownscaleByTwoGetsCorrectPixelCenters) {
98         const int size = 5;
99
100         // This isn't a perfect dot, since the Lanczos filter has a slight
101         // sharpening effect; the most important thing is that we have kept
102         // the texel center right (everything is nicely symmetric).
103         // The approximate magnitudes have been checked against ImageMagick.
104         float expected_data[size * size] = {
105                  0.0045, -0.0067, -0.0599, -0.0067,  0.0045,
106                 -0.0067,  0.0100,  0.0892,  0.0100, -0.0067,
107                 -0.0599,  0.0890,  0.7925,  0.0892, -0.0599,
108                 -0.0067,  0.0100,  0.0890,  0.0100, -0.0067,
109                  0.0045, -0.0067, -0.0599, -0.0067,  0.0045,
110         };
111         float data[size * size * 4], out_data[size * size];
112
113         for (int y = 0; y < size * 2; ++y) {
114                 for (int x = 0; x < size * 2; ++x) {
115                         float weight = lanczos((x - size + 0.5f) * 0.5f, 3.0f);
116                         weight *= lanczos((y - size + 0.5f) * 0.5f, 3.0f);
117                         data[y * (size * 2) + x] = weight;
118                 }
119         }
120
121         EffectChainTester tester(nullptr, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
122
123         ImageFormat format;
124         format.color_space = COLORSPACE_sRGB;
125         format.gamma_curve = GAMMA_LINEAR;
126
127         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size * 2, size * 2);
128         input->set_pixel_data(data);
129         tester.get_chain()->add_input(input);
130
131         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
132         ASSERT_TRUE(resample_effect->set_int("width", size));
133         ASSERT_TRUE(resample_effect->set_int("height", size));
134         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
135
136         expect_equal(expected_data, out_data, size, size);
137 }
138
139 TEST(ResampleEffectTest, UpscaleByThreeGetsCorrectPixelCenters) {
140         const int size = 5;
141
142         float data[size * size] = {
143                 0.0, 0.0, 0.0, 0.0, 0.0,
144                 0.0, 0.0, 0.0, 0.0, 0.0,
145                 0.0, 0.0, 1.0, 0.0, 0.0,
146                 0.0, 0.0, 0.0, 0.0, 0.0,
147                 0.0, 0.0, 0.0, 0.0, 0.0,
148         };
149         float out_data[size * size * 9];
150
151         EffectChainTester tester(nullptr, size * 3, size * 3, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
152
153         ImageFormat format;
154         format.color_space = COLORSPACE_sRGB;
155         format.gamma_curve = GAMMA_LINEAR;
156
157         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, size, size);
158         input->set_pixel_data(data);
159         tester.get_chain()->add_input(input);
160
161         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
162         ASSERT_TRUE(resample_effect->set_int("width", size * 3));
163         ASSERT_TRUE(resample_effect->set_int("height", size * 3));
164         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
165
166         // We only bother checking that the middle pixel is still correct,
167         // and that symmetry holds.
168         EXPECT_FLOAT_EQ(1.0, out_data[7 * (size * 3) + 7]);
169         for (unsigned y = 0; y < size * 3; ++y) {
170                 for (unsigned x = 0; x < size * 3; ++x) {
171                         EXPECT_NEAR(out_data[y * (size * 3) + x], out_data[(size * 3 - y - 1) * (size * 3) + x], 1e-6);
172                         EXPECT_NEAR(out_data[y * (size * 3) + x], out_data[y * (size * 3) + (size * 3 - x - 1)], 1e-6);
173                 }
174         }
175 }
176
177 TEST(ResampleEffectTest, HeavyResampleGetsSumRight) {
178         // Do only one resample pass, more specifically the last one, which goes to
179         // our fp32 output. This allows us to analyze the precision without intermediate
180         // fp16 rounding.
181         const int swidth = 1, sheight = 1280;
182         const int dwidth = 1, dheight = 64;
183
184         float data[swidth * sheight], out_data[dwidth * dheight], expected_data[dwidth * dheight];
185         for (int y = 0; y < sheight; ++y) {
186                 for (int x = 0; x < swidth; ++x) {
187                         data[y * swidth + x] = 1.0f;
188                 }
189         }
190         for (int y = 0; y < dheight; ++y) {
191                 for (int x = 0; x < dwidth; ++x) {
192                         expected_data[y * dwidth + x] = 1.0f;
193                 }
194         }
195
196         EffectChainTester tester(nullptr, dwidth, dheight, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR, GL_RGBA32F);
197
198         ImageFormat format;
199         format.color_space = COLORSPACE_sRGB;
200         format.gamma_curve = GAMMA_LINEAR;
201
202         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, swidth, sheight);
203         input->set_pixel_data(data);
204
205         tester.get_chain()->add_input(input);
206         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
207         ASSERT_TRUE(resample_effect->set_int("width", dwidth));
208         ASSERT_TRUE(resample_effect->set_int("height", dheight));
209         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
210
211         // Require that we are within 10-bit accuracy. Note that this limit is for
212         // one pass only, but the limit is tight enough that it should be good enough
213         // for 10-bit accuracy even after two passes.
214         expect_equal(expected_data, out_data, dwidth, dheight, 0.12 / 1023.0);
215 }
216
217 TEST(ResampleEffectTest, ReadWholePixelFromLeft) {
218         const int size = 5;
219
220         float data[size * size] = {
221                 0.0, 0.0, 0.0, 0.0, 0.0,
222                 0.0, 0.0, 0.0, 0.0, 0.0,
223                 0.0, 0.0, 1.0, 0.0, 0.0,
224                 0.0, 0.0, 0.0, 0.0, 0.0,
225                 0.0, 0.0, 0.0, 0.0, 0.0,
226         };
227         float expected_data[size * size] = {
228                 0.0, 0.0, 0.0, 0.0, 0.0,
229                 0.0, 0.0, 0.0, 0.0, 0.0,
230                 0.0, 1.0, 0.0, 0.0, 0.0,
231                 0.0, 0.0, 0.0, 0.0, 0.0,
232                 0.0, 0.0, 0.0, 0.0, 0.0,
233         };
234         float out_data[size * size];
235
236         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
237         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
238         ASSERT_TRUE(resample_effect->set_int("width", size));
239         ASSERT_TRUE(resample_effect->set_int("height", size));
240         ASSERT_TRUE(resample_effect->set_float("left", 1.0f));
241         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
242
243         expect_equal(expected_data, out_data, size, size);
244 }
245
246 TEST(ResampleEffectTest, ReadQuarterPixelFromLeft) {
247         const int size = 5;
248
249         float data[size * size] = {
250                 0.0, 0.0, 0.0, 0.0, 0.0,
251                 0.0, 0.0, 0.0, 0.0, 0.0,
252                 0.0, 0.0, 1.0, 0.0, 0.0,
253                 0.0, 0.0, 0.0, 0.0, 0.0,
254                 0.0, 0.0, 0.0, 0.0, 0.0,
255         };
256
257         float expected_data[size * size] = {
258                 0.0, 0.0, 0.0, 0.0, 0.0,
259                 0.0, 0.0, 0.0, 0.0, 0.0,
260
261                 // sin(x*pi)/(x*pi) * sin(x*pi/3)/(x*pi/3) for
262                 // x = -1.75, -0.75, 0.25, 1.25, 2.25.
263                 // Note that the weight is mostly on the left side.
264                 -0.06779, 0.27019, 0.89007, -0.13287, 0.03002,
265
266                 0.0, 0.0, 0.0, 0.0, 0.0,
267                 0.0, 0.0, 0.0, 0.0, 0.0,
268         };
269         float out_data[size * size];
270
271         EffectChainTester tester(data, size, size, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
272         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
273         ASSERT_TRUE(resample_effect->set_int("width", size));
274         ASSERT_TRUE(resample_effect->set_int("height", size));
275         ASSERT_TRUE(resample_effect->set_float("left", 0.25f));
276         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
277
278         expect_equal(expected_data, out_data, size, size);
279 }
280
281 TEST(ResampleEffectTest, ReadQuarterPixelFromTop) {
282         const int width = 3;
283         const int height = 5;
284
285         float data[width * height] = {
286                 0.0, 0.0, 0.0,
287                 0.0, 0.0, 0.0,
288                 1.0, 0.0, 0.0,
289                 0.0, 0.0, 0.0,
290                 0.0, 0.0, 0.0,
291         };
292
293         // See ReadQuarterPixelFromLeft for explanation of the data.
294         float expected_data[width * height] = {
295                 -0.06779, 0.0, 0.0,
296                  0.27019, 0.0, 0.0,
297                  0.89007, 0.0, 0.0,
298                 -0.13287, 0.0, 0.0,
299                  0.03002, 0.0, 0.0,
300         };
301         float out_data[width * height];
302
303         EffectChainTester tester(data, width, height, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
304         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
305         ASSERT_TRUE(resample_effect->set_int("width", width));
306         ASSERT_TRUE(resample_effect->set_int("height", height));
307         ASSERT_TRUE(resample_effect->set_float("top", 0.25f));
308         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
309
310         expect_equal(expected_data, out_data, width, height);
311 }
312
313 TEST(ResampleEffectTest, ReadHalfPixelFromLeftAndScale) {
314         const int src_width = 4;
315         const int dst_width = 8;
316
317         float data[src_width * 1] = {
318                 1.0, 2.0, 3.0, 4.0,
319         };
320         float expected_data[dst_width * 1] = {
321                 // Empirical; the real test is that we are the same for 0.499 and 0.501.
322                 1.1553, 1.7158, 2.2500, 2.7461, 3.2812, 3.8418, 4.0703, 4.0508
323         };
324         float out_data[dst_width * 1];
325
326         EffectChainTester tester(nullptr, dst_width, 1, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
327
328         ImageFormat format;
329         format.color_space = COLORSPACE_sRGB;
330         format.gamma_curve = GAMMA_LINEAR;
331
332         FlatInput *input = new FlatInput(format, FORMAT_GRAYSCALE, GL_FLOAT, src_width, 1);
333         input->set_pixel_data(data);
334         tester.get_chain()->add_input(input);
335
336         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
337         ASSERT_TRUE(resample_effect->set_int("width", dst_width));
338         ASSERT_TRUE(resample_effect->set_int("height", 1));
339
340         // Check that we are (almost) the same no matter the rounding.
341         ASSERT_TRUE(resample_effect->set_float("left", 0.499f));
342         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
343         expect_equal(expected_data, out_data, dst_width, 1, 1.5f / 255.0f, 0.4f / 255.0f);
344
345         ASSERT_TRUE(resample_effect->set_float("left", 0.501f));
346         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
347         expect_equal(expected_data, out_data, dst_width, 1, 1.5f / 255.0f, 0.4f / 255.0f);
348 }
349
350 TEST(ResampleEffectTest, Zoom) {
351         const int width = 5;
352         const int height = 3;
353
354         float data[width * height] = {
355                 0.0, 0.0, 0.0, 0.0, 0.0,
356                 0.2, 0.4, 0.6, 0.4, 0.2,
357                 0.0, 0.0, 0.0, 0.0, 0.0,
358         };
359         float expected_data[width * height] = {
360                 0.0, 0.0,    0.0, 0.0,    0.0,
361                 0.4, 0.5396, 0.6, 0.5396, 0.4,
362                 0.0, 0.0,    0.0, 0.0,    0.0,
363         };
364         float out_data[width * height];
365
366         EffectChainTester tester(data, width, height, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
367         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
368         ASSERT_TRUE(resample_effect->set_int("width", width));
369         ASSERT_TRUE(resample_effect->set_int("height", height));
370         ASSERT_TRUE(resample_effect->set_float("zoom_x", 2.0f));
371         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
372
373         expect_equal(expected_data, out_data, width, height);
374 }
375
376 TEST(ResampleEffectTest, VerticalZoomFromTop) {
377         const int width = 5;
378         const int height = 5;
379
380         float data[width * height] = {
381                 0.2, 0.4, 0.6, 0.4, 0.2,
382                 0.0, 0.0, 0.0, 0.0, 0.0,
383                 0.0, 0.0, 0.0, 0.0, 0.0,
384                 0.0, 0.0, 0.0, 0.0, 0.0,
385                 0.0, 0.0, 0.0, 0.0, 0.0,
386         };
387
388         // Largely empirical data; the main point is that the top line
389         // is unchanged, since that's our zooming point.
390         float expected_data[width * height] = {
391                  0.2000,  0.4000,  0.6000,  0.4000,  0.2000,
392                  0.1389,  0.2778,  0.4167,  0.2778,  0.1389,
393                  0.0600,  0.1199,  0.1798,  0.1199,  0.0600,
394                  0.0000,  0.0000,  0.0000,  0.0000,  0.0000,
395                 -0.0229, -0.0459, -0.0688, -0.0459, -0.0229,
396         };
397         float out_data[width * height];
398
399         EffectChainTester tester(data, width, height, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
400         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
401         ASSERT_TRUE(resample_effect->set_int("width", width));
402         ASSERT_TRUE(resample_effect->set_int("height", height));
403         ASSERT_TRUE(resample_effect->set_float("zoom_y", 3.0f));
404         ASSERT_TRUE(resample_effect->set_float("zoom_center_y", 0.5f / height));
405         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
406
407         expect_equal(expected_data, out_data, width, height);
408 }
409
410 TEST(ResampleEffectTest, Precision) {
411         const int size = 1920;  // Difficult non-power-of-two size.
412         const int offset = 5;
413
414         // Deliberately put the data of interest very close to the right,
415         // where texture coordinates are farther from 0 and thus less precise.
416         float data[size * 2] = {0};
417         data[size - offset] = 1.0f;
418         float expected_data[size * 2] = {0};
419         for (int x = 0; x < size * 2; ++x) {
420                 expected_data[x] = lanczos((x - (size - 2 * offset + 1) + 0.5f) * 0.5f, 3.0f);
421         }
422         float out_data[size * 2];
423
424         EffectChainTester tester(data, size * 2, 1, FORMAT_GRAYSCALE, COLORSPACE_sRGB, GAMMA_LINEAR);
425         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
426         ASSERT_TRUE(resample_effect->set_int("width", size * 2));
427         ASSERT_TRUE(resample_effect->set_int("height", 1));
428         ASSERT_TRUE(resample_effect->set_float("zoom_x", 2.0f));
429         tester.run(out_data, GL_RED, COLORSPACE_sRGB, GAMMA_LINEAR);
430
431         expect_equal(expected_data, out_data, size, 1);
432 }
433
434 #ifdef HAVE_BENCHMARK
435 template<> inline uint8_t from_fp32<uint8_t>(float x) { return x; }
436
437 template<class T>
438 void BM_ResampleEffect(benchmark::State &state, GammaCurve gamma_curve, GLenum output_format, const std::string &shader_type)
439 {
440         DisableComputeShadersTemporarily disabler(shader_type == "fragment");
441         if (disabler.should_skip(&state)) return;
442
443         unsigned in_width = state.range(0), in_height = state.range(1);
444         unsigned out_width = state.range(2), out_height = state.range(3);
445
446         unique_ptr<T[]> data(new T[in_width * in_height * 4]);
447         unique_ptr<T[]> out_data(new T[out_width * out_height * 4]);
448
449         for (unsigned i = 0; i < in_width * in_height * 4; ++i) {
450                 data[i] = from_fp32<T>(float(rand()));
451         }
452
453         EffectChainTester tester(nullptr, out_width, out_height, FORMAT_BGRA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, gamma_curve, output_format);
454         tester.add_input(data.get(), FORMAT_BGRA_POSTMULTIPLIED_ALPHA, COLORSPACE_sRGB, gamma_curve, in_width, in_height);
455         Effect *resample_effect = tester.get_chain()->add_effect(new ResampleEffect());
456
457         ASSERT_TRUE(resample_effect->set_int("width", out_width));
458         ASSERT_TRUE(resample_effect->set_int("height", out_height));
459
460         tester.benchmark(state, out_data.get(), GL_BGRA, COLORSPACE_sRGB, gamma_curve, OUTPUT_ALPHA_FORMAT_PREMULTIPLIED);
461 }
462
463 void BM_ResampleEffectHalf(benchmark::State &state, GammaCurve gamma_curve, const std::string &shader_type)
464 {
465         BM_ResampleEffect<fp16_int_t>(state, gamma_curve, GL_RGBA16F, shader_type);
466 }
467
468 void BM_ResampleEffectInt8(benchmark::State &state, GammaCurve gamma_curve, const std::string &shader_type)
469 {
470         BM_ResampleEffect<uint8_t>(state, gamma_curve, GL_RGBA8, shader_type);
471 }
472
473 BENCHMARK_CAPTURE(BM_ResampleEffectInt8, Int8Upscale, GAMMA_REC_709, "fragment")->Args({640, 360, 1280, 720})->Args({320, 180, 1280, 720})->Args({321, 181, 1280, 720})->UseRealTime()->Unit(benchmark::kMicrosecond);
474 BENCHMARK_CAPTURE(BM_ResampleEffectHalf, Float16Upscale, GAMMA_LINEAR, "fragment")->Args({640, 360, 1280, 720})->Args({320, 180, 1280, 720})->Args({321, 181, 1280, 720})->UseRealTime()->Unit(benchmark::kMicrosecond);
475 BENCHMARK_CAPTURE(BM_ResampleEffectInt8, Int8Downscale, GAMMA_REC_709, "fragment")->Args({1280, 720, 640, 360})->Args({1280, 720, 320, 180})->Args({1280, 720, 321, 181})->UseRealTime()->Unit(benchmark::kMicrosecond);
476 BENCHMARK_CAPTURE(BM_ResampleEffectHalf, Float16Downscale, GAMMA_LINEAR, "fragment")->Args({1280, 720, 640, 360})->Args({1280, 720, 320, 180})->Args({1280, 720, 321, 181})->UseRealTime()->Unit(benchmark::kMicrosecond);
477
478 void BM_ComputeScalingWeights(benchmark::State &state)
479 {
480         constexpr unsigned src_size = 1280;
481         constexpr unsigned dst_size = 35;
482         int old_precision = movit_texel_subpixel_precision;
483         movit_texel_subpixel_precision = 64;  // To get consistent results across GPUs; this is a CPU test.
484
485         // One iteration warmup to make sure the Lanczos table is computed.
486         calculate_scaling_weights(src_size, dst_size, 0.999f, 0.0f);
487
488         for (auto _ : state) {
489                 ScalingWeights weights = calculate_scaling_weights(src_size, dst_size, 0.999f, 0.0f);
490         }
491
492         movit_texel_subpixel_precision = old_precision;
493 }
494 BENCHMARK(BM_ComputeScalingWeights)->Unit(benchmark::kMicrosecond);
495
496 #endif
497
498 }  // namespace movit