Blender V4.5
IMB_scaling_performance_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
7#include "IMB_imbuf.hh"
8
9#include "BLI_math_base.hh"
10#include "BLI_math_matrix.hh"
11#include "BLI_timeit.hh"
12
13using namespace blender;
14
15static constexpr int SRC_X = 5123;
16static constexpr int SRC_Y = 4091;
17
18static constexpr int DST_SMALLER_X = int(SRC_X * 0.21f);
19static constexpr int DST_SMALLER_Y = int(SRC_Y * 0.67f);
20
21static constexpr int DST_LARGER_X = int(SRC_X * 1.19f);
22static constexpr int DST_LARGER_Y = int(SRC_Y * 2.13f);
23
24static ImBuf *create_src_image(bool use_float)
25{
26 ImBuf *img = IMB_allocImBuf(SRC_X, SRC_Y, 32, use_float ? IB_float_data : IB_byte_data);
27 if (use_float) {
28 const size_t img_pixel_count = IMB_get_pixel_count(img);
29 float *pix = img->float_buffer.data;
30 for (size_t i = 0; i < img_pixel_count; i++) {
31 pix[0] = i * 0.1f;
32 pix[1] = i * 2.1f;
33 pix[2] = i * 0.01f;
34 pix[3] = math::mod(i * 0.03f, 2.0f);
35 pix += 4;
36 }
37 }
38 else {
39 const size_t img_pixel_count = IMB_get_pixel_count(img);
40 uchar *pix = img->byte_buffer.data;
41 for (size_t i = 0; i < img_pixel_count; i++) {
42 pix[0] = i & 0xFF;
43 pix[1] = (i * 3) & 0xFF;
44 pix[2] = (i + 12345) & 0xFF;
45 pix[3] = (i / 4) & 0xFF;
46 pix += 4;
47 }
48 }
49 return img;
50}
51
53 int width,
54 int height,
56{
57 ImBuf *dst = IMB_allocImBuf(width, height, src->planes, src->flags);
59 float3(float(src->x) / dst->x, float(src->y) / dst->y, 1.0f));
60 IMB_transform(src, dst, IMB_TRANSFORM_MODE_REGULAR, filter, matrix, nullptr);
61 IMB_freeImBuf(src);
62 src = dst;
63}
64
65static void imb_xform_nearest(ImBuf *&src, int width, int height)
66{
68}
69static void imb_xform_bilinear(ImBuf *&src, int width, int height)
70{
72}
73static void imb_xform_box(ImBuf *&src, int width, int height)
74{
76 width,
77 height,
78 width < src->x && height < src->y ? IMB_FILTER_BOX :
80}
81static void imb_scale_nearest_st(ImBuf *&src, int width, int height)
82{
83 IMB_scale(src, width, height, IMBScaleFilter::Nearest, false);
84}
85static void imb_scale_nearest(ImBuf *&src, int width, int height)
86{
87 IMB_scale(src, width, height, IMBScaleFilter::Nearest, true);
88}
89static void imb_scale_bilinear_st(ImBuf *&src, int width, int height)
90{
91 IMB_scale(src, width, height, IMBScaleFilter::Bilinear, false);
92}
93static void imb_scale_bilinear(ImBuf *&src, int width, int height)
94{
95 IMB_scale(src, width, height, IMBScaleFilter::Bilinear, true);
96}
97static void imb_scale_box_st(ImBuf *&src, int width, int height)
98{
99 IMB_scale(src, width, height, IMBScaleFilter::Box, false);
100}
101static void imb_scale_box(ImBuf *&src, int width, int height)
102{
103 IMB_scale(src, width, height, IMBScaleFilter::Box, true);
104}
105
106static void scale_perf_impl(const char *name,
107 bool use_float,
108 void (*func)(ImBuf *&src, int width, int height))
109{
110 ImBuf *img = create_src_image(use_float);
111 {
112 SCOPED_TIMER(name);
113 func(img, DST_LARGER_X, DST_LARGER_Y);
114 func(img, SRC_X, SRC_Y);
115 func(img, DST_SMALLER_X, DST_SMALLER_Y);
116 func(img, DST_LARGER_X, DST_LARGER_Y);
117 }
118 IMB_freeImBuf(img);
119}
120
121static void test_scaling_perf(bool use_float)
122{
123 scale_perf_impl("scale_neare_s", use_float, imb_scale_nearest_st);
124 scale_perf_impl("scale_neare_m", use_float, imb_scale_nearest);
125 scale_perf_impl("xform_neare_m", use_float, imb_xform_nearest);
126
127 scale_perf_impl("scale_bilin_s", use_float, imb_scale_bilinear_st);
128 scale_perf_impl("scale_bilin_m", use_float, imb_scale_bilinear);
129 scale_perf_impl("xform_bilin_m", use_float, imb_xform_bilinear);
130
131 scale_perf_impl("scale_boxfl_s", use_float, imb_scale_box_st);
132 scale_perf_impl("scale_boxfl_m", use_float, imb_scale_box);
133 scale_perf_impl("xform_boxfl_m", use_float, imb_xform_box);
134}
135
136TEST(imbuf_scaling, scaling_perf_byte)
137{
138 test_scaling_perf(false);
139}
140
141TEST(imbuf_scaling, scaling_perf_float)
142{
143 test_scaling_perf(true);
144}
unsigned char uchar
#define SCOPED_TIMER(name)
Definition BLI_timeit.hh:70
void IMB_transform(const ImBuf *src, ImBuf *dst, eIMBTransformMode mode, eIMBInterpolationFilterMode filter, const blender::float3x3 &transform_matrix, const rctf *src_crop)
Transform source image buffer onto destination image buffer using a transform matrix.
@ IMB_TRANSFORM_MODE_REGULAR
Do not crop or repeat.
Definition IMB_imbuf.hh:588
void IMB_freeImBuf(ImBuf *ibuf)
size_t IMB_get_pixel_count(const ImBuf *ibuf)
Get the length of the data of the given image buffer in pixels.
ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
bool IMB_scale(ImBuf *ibuf, unsigned int newx, unsigned int newy, IMBScaleFilter filter, bool threaded=true)
Definition scaling.cc:777
eIMBInterpolationFilterMode
Definition IMB_imbuf.hh:287
@ IMB_FILTER_NEAREST
Definition IMB_imbuf.hh:288
@ IMB_FILTER_BILINEAR
Definition IMB_imbuf.hh:289
@ IMB_FILTER_BOX
Definition IMB_imbuf.hh:292
@ IB_float_data
@ IB_byte_data
static void imb_scale_box_st(ImBuf *&src, int width, int height)
static void imb_scale_bilinear_st(ImBuf *&src, int width, int height)
static constexpr int SRC_Y
static void scale_perf_impl(const char *name, bool use_float, void(*func)(ImBuf *&src, int width, int height))
static constexpr int DST_SMALLER_Y
static void test_scaling_perf(bool use_float)
static constexpr int DST_LARGER_Y
static void imb_xform_nearest(ImBuf *&src, int width, int height)
static constexpr int SRC_X
static void imb_xform_box(ImBuf *&src, int width, int height)
static void imb_scale_nearest_st(ImBuf *&src, int width, int height)
static constexpr int DST_LARGER_X
static void imb_scale_bilinear(ImBuf *&src, int width, int height)
static void imb_scale_via_transform(ImBuf *&src, int width, int height, eIMBInterpolationFilterMode filter)
static void imb_scale_nearest(ImBuf *&src, int width, int height)
static void imb_xform_bilinear(ImBuf *&src, int width, int height)
static constexpr int DST_SMALLER_X
static void imb_scale_box(ImBuf *&src, int width, int height)
static ImBuf * create_src_image(bool use_float)
#define filter
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
T mod(const T &a, const T &b)
TEST(BLI_string_utils, BLI_string_replace)
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
static void imb_scale_box(ImBuf *ibuf, uint newx, uint newy, bool threaded)
Definition scaling.cc:677
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
unsigned char planes
i
Definition text_draw.cc:230