Blender V4.3
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_rectfloat : IB_rect);
27 if (use_float) {
28 float *pix = img->float_buffer.data;
29 for (int i = 0; i < img->x * img->y; i++) {
30 pix[0] = i * 0.1f;
31 pix[1] = i * 2.1f;
32 pix[2] = i * 0.01f;
33 pix[3] = math::mod(i * 0.03f, 2.0f);
34 pix += 4;
35 }
36 }
37 else {
38 uchar *pix = img->byte_buffer.data;
39 for (int i = 0; i < img->x * img->y; i++) {
40 pix[0] = i & 0xFF;
41 pix[1] = (i * 3) & 0xFF;
42 pix[2] = (i + 12345) & 0xFF;
43 pix[3] = (i / 4) & 0xFF;
44 pix += 4;
45 }
46 }
47 return img;
48}
49
51 int width,
52 int height,
54{
55 ImBuf *dst = IMB_allocImBuf(width, height, src->planes, src->flags);
57 float4(float(src->x) / dst->x, float(src->y) / dst->y, 1.0f, 1.0f));
58 IMB_transform(src, dst, IMB_TRANSFORM_MODE_REGULAR, filter, matrix.ptr(), nullptr);
59 IMB_freeImBuf(src);
60 src = dst;
61}
62
63static void imb_xform_nearest(ImBuf *&src, int width, int height)
64{
66}
67static void imb_xform_bilinear(ImBuf *&src, int width, int height)
68{
70}
71static void imb_xform_box(ImBuf *&src, int width, int height)
72{
74 width,
75 height,
76 width < src->x && height < src->y ? IMB_FILTER_BOX :
78}
79static void imb_scale_nearest_st(ImBuf *&src, int width, int height)
80{
81 IMB_scale(src, width, height, IMBScaleFilter::Nearest, false);
82}
83static void imb_scale_nearest(ImBuf *&src, int width, int height)
84{
85 IMB_scale(src, width, height, IMBScaleFilter::Nearest, true);
86}
87static void imb_scale_bilinear_st(ImBuf *&src, int width, int height)
88{
89 IMB_scale(src, width, height, IMBScaleFilter::Bilinear, false);
90}
91static void imb_scale_bilinear(ImBuf *&src, int width, int height)
92{
93 IMB_scale(src, width, height, IMBScaleFilter::Bilinear, true);
94}
95static void imb_scale_box_st(ImBuf *&src, int width, int height)
96{
97 IMB_scale(src, width, height, IMBScaleFilter::Box, false);
98}
99static void imb_scale_box(ImBuf *&src, int width, int height)
100{
101 IMB_scale(src, width, height, IMBScaleFilter::Box, true);
102}
103
104static void scale_perf_impl(const char *name,
105 bool use_float,
106 void (*func)(ImBuf *&src, int width, int height))
107{
108 ImBuf *img = create_src_image(use_float);
109 {
110 SCOPED_TIMER(name);
111 func(img, DST_LARGER_X, DST_LARGER_Y);
112 func(img, SRC_X, SRC_Y);
113 func(img, DST_SMALLER_X, DST_SMALLER_Y);
114 func(img, DST_LARGER_X, DST_LARGER_Y);
115 }
116 IMB_freeImBuf(img);
117}
118
119static void test_scaling_perf(bool use_float)
120{
121 scale_perf_impl("scale_neare_s", use_float, imb_scale_nearest_st);
122 scale_perf_impl("scale_neare_m", use_float, imb_scale_nearest);
123 scale_perf_impl("xform_neare_m", use_float, imb_xform_nearest);
124
125 scale_perf_impl("scale_bilin_s", use_float, imb_scale_bilinear_st);
126 scale_perf_impl("scale_bilin_m", use_float, imb_scale_bilinear);
127 scale_perf_impl("xform_bilin_m", use_float, imb_xform_bilinear);
128
129 scale_perf_impl("scale_boxfl_s", use_float, imb_scale_box_st);
130 scale_perf_impl("scale_boxfl_m", use_float, imb_scale_box);
131 scale_perf_impl("xform_boxfl_m", use_float, imb_xform_box);
132}
133
134TEST(imbuf_scaling, scaling_perf_byte)
135{
136 test_scaling_perf(false);
137}
138
139TEST(imbuf_scaling, scaling_perf_float)
140{
141 test_scaling_perf(true);
142}
unsigned char uchar
#define SCOPED_TIMER(name)
Definition BLI_timeit.hh:61
@ IMB_TRANSFORM_MODE_REGULAR
Do not crop or repeat.
Definition IMB_imbuf.hh:678
void IMB_transform(const ImBuf *src, ImBuf *dst, eIMBTransformMode mode, eIMBInterpolationFilterMode filter, const float transform_matrix[4][4], const rctf *src_crop)
Transform source image buffer onto destination image buffer using a transform matrix.
bool IMB_scale(ImBuf *ibuf, unsigned int newx, unsigned int newy, IMBScaleFilter filter, bool threaded=true)
Definition scaling.cc:779
eIMBInterpolationFilterMode
Definition IMB_imbuf.hh:288
@ IMB_FILTER_NEAREST
Definition IMB_imbuf.hh:289
@ IMB_FILTER_BILINEAR
Definition IMB_imbuf.hh:290
@ IMB_FILTER_BOX
Definition IMB_imbuf.hh:293
@ IB_rectfloat
@ IB_rect
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)
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
struct ImBuf * IMB_allocImBuf(unsigned int, unsigned int, unsigned char, unsigned int)
void IMB_freeImBuf(ImBuf *)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
T mod(const T &a, const T &b)
TEST(BLI_string_utils, BLI_uniquename_cb)
VecBase< float, 4 > float4
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
unsigned char planes