FreeRDP
Loading...
Searching...
No Matches
benchmark.c
1
21#include <stdio.h>
22
23#include <winpr/crypto.h>
24#include <winpr/sysinfo.h>
25#include <freerdp/primitives.h>
26
27typedef struct
28{
29 BYTE* channels[3];
30 UINT32 steps[3];
31 prim_size_t roi;
32 BYTE* outputBuffer;
33 BYTE* outputChannels[3];
34 BYTE* rgbBuffer;
35 UINT32 outputStride;
36 UINT32 testedFormat;
37} primitives_YUV_benchmark;
38
39static void primitives_YUV_benchmark_free(primitives_YUV_benchmark* bench)
40{
41 if (!bench)
42 return;
43
44 free(bench->outputBuffer);
45 free(bench->rgbBuffer);
46
47 for (size_t i = 0; i < 3; i++)
48 {
49 free(bench->outputChannels[i]);
50 free(bench->channels[i]);
51 }
52
53 const primitives_YUV_benchmark empty = WINPR_C_ARRAY_INIT;
54 *bench = empty;
55}
56
57static primitives_YUV_benchmark primitives_YUV_benchmark_init(void)
58{
59 primitives_YUV_benchmark ret = WINPR_C_ARRAY_INIT;
60 ret.roi.width = 3840 * 4;
61 ret.roi.height = 2160 * 4;
62 ret.outputStride = ret.roi.width * 4;
63 ret.testedFormat = PIXEL_FORMAT_BGRA32;
64
65 ret.outputBuffer = calloc(ret.outputStride, ret.roi.height);
66 if (!ret.outputBuffer)
67 goto fail;
68 ret.rgbBuffer = calloc(ret.outputStride, ret.roi.height);
69 if (!ret.rgbBuffer)
70 goto fail;
71 if (winpr_RAND(ret.rgbBuffer, 1ULL * ret.outputStride * ret.roi.height) < 0)
72 goto fail;
73
74 for (size_t i = 0; i < 3; i++)
75 {
76 ret.channels[i] = calloc(ret.roi.width, ret.roi.height);
77 ret.outputChannels[i] = calloc(ret.roi.width, ret.roi.height);
78 if (!ret.channels[i] || !ret.outputChannels[i])
79 goto fail;
80
81 if (winpr_RAND(ret.channels[i], 1ull * ret.roi.width * ret.roi.height) < 0)
82 goto fail;
83 ret.steps[i] = ret.roi.width;
84 }
85
86 return ret;
87
88fail:
89 primitives_YUV_benchmark_free(&ret);
90 return ret;
91}
92
93static const char* print_time(UINT64 t, char* buffer, size_t size)
94{
95 (void)_snprintf(buffer, size, "%u.%03u.%03u.%03u", (unsigned)(t / 1000000000ull),
96 (unsigned)((t / 1000000ull) % 1000), (unsigned)((t / 1000ull) % 1000),
97 (unsigned)((t) % 1000));
98 return buffer;
99}
100
101static BOOL primitives_YUV420_benchmark_run(primitives_YUV_benchmark* bench, primitives_t* prims)
102{
103 const BYTE* channels[3] = WINPR_C_ARRAY_INIT;
104
105 for (size_t i = 0; i < 3; i++)
106 channels[i] = bench->channels[i];
107
108 for (size_t x = 0; x < 10; x++)
109 {
110 const UINT64 start = winpr_GetTickCount64NS();
111 pstatus_t status =
112 prims->YUV420ToRGB_8u_P3AC4R(channels, bench->steps, bench->outputBuffer,
113 bench->outputStride, bench->testedFormat, &bench->roi);
114 const UINT64 end = winpr_GetTickCount64NS();
115 if (status != PRIMITIVES_SUCCESS)
116 {
117 (void)fprintf(stderr, "Running YUV420ToRGB_8u_P3AC4R failed\n");
118 return FALSE;
119 }
120 const UINT64 diff = end - start;
121 char buffer[32] = WINPR_C_ARRAY_INIT;
122 printf("[%" PRIuz "] YUV420ToRGB_8u_P3AC4R %" PRIu32 "x%" PRIu32 " took %sns\n", x,
123 bench->roi.width, bench->roi.height, print_time(diff, buffer, sizeof(buffer)));
124 }
125
126 return TRUE;
127}
128
129static BOOL primitives_YUV444_benchmark_run(primitives_YUV_benchmark* bench, primitives_t* prims)
130{
131 const BYTE* channels[3] = WINPR_C_ARRAY_INIT;
132
133 for (size_t i = 0; i < 3; i++)
134 channels[i] = bench->channels[i];
135
136 for (size_t x = 0; x < 10; x++)
137 {
138 const UINT64 start = winpr_GetTickCount64NS();
139 pstatus_t status =
140 prims->YUV444ToRGB_8u_P3AC4R(channels, bench->steps, bench->outputBuffer,
141 bench->outputStride, bench->testedFormat, &bench->roi);
142 const UINT64 end = winpr_GetTickCount64NS();
143 if (status != PRIMITIVES_SUCCESS)
144 {
145 (void)fprintf(stderr, "Running YUV444ToRGB_8u_P3AC4R failed\n");
146 return FALSE;
147 }
148 const UINT64 diff = end - start;
149 char buffer[32] = WINPR_C_ARRAY_INIT;
150 printf("[%" PRIuz "] YUV444ToRGB_8u_P3AC4R %" PRIu32 "x%" PRIu32 " took %sns\n", x,
151 bench->roi.width, bench->roi.height, print_time(diff, buffer, sizeof(buffer)));
152 }
153
154 return TRUE;
155}
156
157static BOOL primitives_RGB2420_benchmark_run(primitives_YUV_benchmark* bench, primitives_t* prims)
158{
159 for (size_t x = 0; x < 10; x++)
160 {
161 const UINT64 start = winpr_GetTickCount64NS();
162 pstatus_t status =
163 prims->RGBToYUV420_8u_P3AC4R(bench->rgbBuffer, bench->testedFormat, bench->outputStride,
164 bench->outputChannels, bench->steps, &bench->roi);
165 const UINT64 end = winpr_GetTickCount64NS();
166 if (status != PRIMITIVES_SUCCESS)
167 {
168 (void)fprintf(stderr, "Running RGBToYUV420_8u_P3AC4R failed\n");
169 return FALSE;
170 }
171 const UINT64 diff = end - start;
172 char buffer[32] = WINPR_C_ARRAY_INIT;
173 printf("[%" PRIuz "] RGBToYUV420_8u_P3AC4R %" PRIu32 "x%" PRIu32 " took %sns\n", x,
174 bench->roi.width, bench->roi.height, print_time(diff, buffer, sizeof(buffer)));
175 }
176
177 return TRUE;
178}
179
180static BOOL primitives_RGB2444_benchmark_run(primitives_YUV_benchmark* bench, primitives_t* prims)
181{
182 for (size_t x = 0; x < 10; x++)
183 {
184 const UINT64 start = winpr_GetTickCount64NS();
185 pstatus_t status =
186 prims->RGBToYUV444_8u_P3AC4R(bench->rgbBuffer, bench->testedFormat, bench->outputStride,
187 bench->outputChannels, bench->steps, &bench->roi);
188 const UINT64 end = winpr_GetTickCount64NS();
189 if (status != PRIMITIVES_SUCCESS)
190 {
191 (void)fprintf(stderr, "Running RGBToYUV444_8u_P3AC4R failed\n");
192 return FALSE;
193 }
194 const UINT64 diff = end - start;
195 char buffer[32] = WINPR_C_ARRAY_INIT;
196 printf("[%" PRIuz "] RGBToYUV444_8u_P3AC4R %" PRIu32 "x%" PRIu32 " took %sns\n", x,
197 bench->roi.width, bench->roi.height, print_time(diff, buffer, sizeof(buffer)));
198 }
199
200 return TRUE;
201}
202
203int main(int argc, char* argv[])
204{
205 WINPR_UNUSED(argc);
206 WINPR_UNUSED(argv);
207 primitives_YUV_benchmark bench = primitives_YUV_benchmark_init();
208
209 for (primitive_hints hint = PRIMITIVES_PURE_SOFT; hint < PRIMITIVES_AUTODETECT; hint++)
210 {
211 const char* hintstr = primtives_hint_str(hint);
212 primitives_t* prim = primitives_get_by_type(hint);
213 if (!prim)
214 {
215 (void)fprintf(stderr, "failed to get primitives: %s\n", hintstr);
216 goto fail;
217 }
218
219 printf("Running YUV420 -> RGB benchmark on %s implementation:\n", hintstr);
220 if (!primitives_YUV420_benchmark_run(&bench, prim))
221 {
222 (void)fprintf(stderr, "YUV420 -> RGB benchmark failed\n");
223 goto fail;
224 }
225 printf("\n");
226
227 printf("Running RGB -> YUV420 benchmark on %s implementation:\n", hintstr);
228 if (!primitives_RGB2420_benchmark_run(&bench, prim))
229 {
230 (void)fprintf(stderr, "RGB -> YUV420 benchmark failed\n");
231 goto fail;
232 }
233 printf("\n");
234
235 printf("Running YUV444 -> RGB benchmark on %s implementation:\n", hintstr);
236 if (!primitives_YUV444_benchmark_run(&bench, prim))
237 {
238 (void)fprintf(stderr, "YUV444 -> RGB benchmark failed\n");
239 goto fail;
240 }
241 printf("\n");
242
243 printf("Running RGB -> YUV444 benchmark on %s implementation:\n", hintstr);
244 if (!primitives_RGB2444_benchmark_run(&bench, prim))
245 {
246 (void)fprintf(stderr, "RGB -> YUV444 benchmark failed\n");
247 goto fail;
248 }
249 printf("\n");
250 }
251fail:
252 primitives_YUV_benchmark_free(&bench);
253 return 0;
254}