17#include <freerdp/config.h>
18#include <winpr/crypto.h>
20#include <winpr/sysinfo.h>
23#define COPY_TESTSIZE (256 * 2 + 16 * 2 + 15 + 15)
26static BOOL test_copy8u_func(
void)
29 BYTE data[COPY_TESTSIZE + 15] = WINPR_C_ARRAY_INIT;
30 if (winpr_RAND(data,
sizeof(data)) < 0)
33 for (
int soff = 0; soff < 16; ++soff)
35 for (
int doff = 0; doff < 16; ++doff)
37 for (
int length = 1; length <= COPY_TESTSIZE - doff; ++length)
39 BYTE dest[COPY_TESTSIZE + 15] = WINPR_C_ARRAY_INIT;
41 if (prims->copy_8u(data + soff, dest + doff, length) != PRIMITIVES_SUCCESS)
44 for (
int i = 0; i < length; ++i)
46 if (dest[i + doff] != data[i + soff])
48 printf(
"COPY8U FAIL: off=%d len=%d, dest[%d]=0x%02" PRIx8
""
49 "data[%d]=0x%02" PRIx8
"\n",
50 doff, length, i + doff, dest[i + doff], i + soff, data[i + soff]);
62static BOOL test_copy8u_speed(
void)
64 BYTE src[MAX_TEST_SIZE + 4] = WINPR_C_ARRAY_INIT;
65 BYTE dst[MAX_TEST_SIZE + 4] = WINPR_C_ARRAY_INIT;
67 if (!speed_test(
"copy_8u",
"aligned", g_Iterations, (speed_test_fkt)generic->copy_8u,
68 (speed_test_fkt)optimized->copy_8u, src, dst, MAX_TEST_SIZE))
71 if (!speed_test(
"copy_8u",
"unaligned", g_Iterations, (speed_test_fkt)generic->copy_8u,
72 (speed_test_fkt)optimized->copy_8u, src + 1, dst + 1, MAX_TEST_SIZE))
78static BYTE* rand_alloc(
size_t w,
size_t h,
size_t bpp,
size_t pad, BYTE** copy)
80 const size_t s = w * bpp + pad;
81 BYTE* ptr = calloc(s, h);
85 if (winpr_RAND(ptr, s * h) < 0)
93 BYTE* ptr2 = calloc(s, h);
99 memcpy(ptr2, ptr, s * h);
105static size_t runcount = 0;
107static BOOL test_copy_no_overlap_off(BOOL verbose, UINT32 srcFormat, UINT32 dstFormat, UINT32 flags,
108 UINT32 pad, UINT32 w, UINT32 h, UINT32 dxoff, UINT32 dyoff,
109 UINT32 sxoff, UINT32 syoff)
119 WINPR_ASSERT(dxoff < w);
120 WINPR_ASSERT(sxoff < w);
121 WINPR_ASSERT(dyoff < h);
122 WINPR_ASSERT(syoff < h);
124 const UINT32 sbpp = FreeRDPGetBytesPerPixel(srcFormat);
125 const UINT32 dbpp = FreeRDPGetBytesPerPixel(dstFormat);
129 (void)fprintf(stderr,
130 "run src: %s, dst: %s [flags 0x%08" PRIx32
"] %" PRIu32
"x%" PRIu32
131 ", soff=%" PRIu32
"x%" PRIu32
", doff=%" PRIu32
"x%" PRIu32
", pad=%" PRIu32
133 FreeRDPGetColorFormatName(srcFormat), FreeRDPGetColorFormatName(dstFormat),
134 flags, w, h, sxoff, syoff, dxoff, dyoff, pad);
137 const UINT32 sstride = (w + sxoff) * sbpp + pad;
138 const UINT32 dstride = (w + dxoff) * dbpp + pad;
139 BYTE* dst2 =
nullptr;
140 BYTE* src2 =
nullptr;
141 BYTE* dst1 = rand_alloc(w + dxoff, h + dyoff, dbpp, pad, &dst2);
142 BYTE* src1 = rand_alloc(w + sxoff, h + syoff, sbpp, pad, &src2);
143 if (!dst1 || !dst2 || !src1 || !src2)
146 if (gen->
copy_no_overlap(dst1, dstFormat, dstride, dxoff, dyoff, w, h, src1, srcFormat, sstride,
147 sxoff, syoff,
nullptr, flags) != PRIMITIVES_SUCCESS)
150 if (memcmp(src1, src2, 1ULL * sstride * h) != 0)
153 if (prims->
copy_no_overlap(dst2, dstFormat, dstride, dxoff, dyoff, w, h, src1, srcFormat,
154 sstride, sxoff, syoff,
nullptr, flags) != PRIMITIVES_SUCCESS)
157 if (memcmp(src1, src2, 1ULL * sstride * h) != 0)
160 if (memcmp(dst1, dst2, 1ULL * dstride * h) != 0)
163 if (flags == FREERDP_KEEP_DST_ALPHA)
165 for (
size_t y = 0; y < h; y++)
167 const BYTE* d1 = &dst1[(y + dyoff) * dstride];
168 const BYTE* d2 = &dst2[(y + dyoff) * dstride];
169 for (
size_t x = 0; x < w; x++)
171 const UINT32 c1 = FreeRDPReadColor(&d1[(x + dxoff) * dbpp], dstFormat);
172 const UINT32 c2 = FreeRDPReadColor(&d2[(x + dxoff) * dbpp], dstFormat);
175 FreeRDPSplitColor(c1, dstFormat,
nullptr,
nullptr,
nullptr, &a1,
nullptr);
176 FreeRDPSplitColor(c2, dstFormat,
nullptr,
nullptr,
nullptr, &a2,
nullptr);
187 (void)fprintf(stderr,
"failed to compare copy_no_overlap(%s -> %s [0x%08" PRIx32
"])\n",
188 FreeRDPGetColorFormatName(srcFormat), FreeRDPGetColorFormatName(dstFormat),
198static BOOL test_copy_no_overlap(BOOL verbose, UINT32 srcFormat, UINT32 dstFormat, UINT32 flags,
199 UINT32 width, UINT32 height)
204 for (UINT32 dxoff = 0; dxoff < mw; dxoff++)
206 for (UINT32 dyoff = 0; dyoff <= mh; dyoff++)
208 for (UINT32 sxoff = 0; sxoff <= mw; sxoff++)
210 for (UINT32 syoff = 0; syoff <= mh; syoff++)
216 for (UINT32 pad = 8; pad <= 12; pad++)
218 if (!test_copy_no_overlap_off(verbose, srcFormat, dstFormat, flags, pad,
219 width, height, dxoff, dyoff, sxoff, syoff))
230int TestPrimitivesCopy(
int argc,
char* argv[])
235 const BOOL verbose = argc > 1;
237 prim_test_setup(FALSE);
239 if (!test_copy8u_func())
242 if (g_TestPrimitivesPerformance)
244 if (!test_copy8u_speed())
248 const UINT32 flags[] = {
250 FREERDP_KEEP_DST_ALPHA,
251 FREERDP_FLIP_HORIZONTAL,
252 FREERDP_KEEP_DST_ALPHA | FREERDP_FLIP_HORIZONTAL,
253#if defined(TEST_ALL_FLAGS)
254 FREERDP_FLIP_VERTICAL,
255 FREERDP_FLIP_VERTICAL | FREERDP_FLIP_HORIZONTAL,
256 FREERDP_KEEP_DST_ALPHA | FREERDP_FLIP_VERTICAL,
257 FREERDP_KEEP_DST_ALPHA | FREERDP_FLIP_VERTICAL | FREERDP_FLIP_HORIZONTAL
260 const UINT32 formats[] = { PIXEL_FORMAT_BGRA32,
263#if defined(TEST_ALL_FLAGS)
276 for (
size_t z = 0; z < ARRAYSIZE(flags); z++)
278 const UINT32 flag = flags[z];
279 for (
size_t x = 0; x < ARRAYSIZE(formats); x++)
281 const UINT32 sformat = formats[x];
282 for (
size_t y = 0; y < ARRAYSIZE(formats); y++)
284 const UINT32 dformat = formats[y];
286 if (!test_copy_no_overlap(verbose, sformat, dformat, flag, 21, 17))
293 (void)fprintf(stderr,
"runcount=%" PRIuz
"\n", runcount);
WINPR_ATTR_NODISCARD fn_copy_no_overlap_t copy_no_overlap