FreeRDP
Loading...
Searching...
No Matches
TestPrimitivesColors.c
1/* test_colors.c
2 * vi:ts=4 sw=4
3 *
4 * (c) Copyright 2012 Hewlett-Packard Development Company, L.P.
5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
6 * not use this file except in compliance with the License. You may obtain
7 * a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11 * or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15#include <freerdp/config.h>
16
17#include <winpr/sysinfo.h>
18#include <freerdp/utils/profiler.h>
19
20#include "prim_test.h"
21
22/* ------------------------------------------------------------------------- */
23static BOOL test_RGBToRGB_16s8u_P3AC4R_func(prim_size_t roi, DWORD DstFormat)
24{
25 INT16* r = nullptr;
26 INT16* g = nullptr;
27 INT16* b = nullptr;
28 BYTE* out1 = nullptr;
29 BYTE* out2 = nullptr;
30 BOOL failed = FALSE;
31 const INT16* ptrs[3];
32 const UINT32 rgbStride = roi.width * 2;
33 const UINT32 dstStride = roi.width * 4;
34 PROFILER_DEFINE(genericProf)
35 PROFILER_DEFINE(optProf)
36 PROFILER_CREATE(genericProf, "RGBToRGB_16s8u_P3AC4R-GENERIC")
37 PROFILER_CREATE(optProf, "RGBToRGB_16s8u_P3AC4R-OPTIMIZED")
38 r = winpr_aligned_calloc(1, 1ULL * rgbStride * roi.height, 16);
39 g = winpr_aligned_calloc(1, 1ULL * rgbStride * roi.height, 16);
40 b = winpr_aligned_calloc(1, 1ULL * rgbStride * roi.height, 16);
41 out1 = winpr_aligned_calloc(1, 1ULL * dstStride * roi.height, 16);
42 out2 = winpr_aligned_calloc(1, 1ULL * dstStride * roi.height, 16);
43
44 if (!r || !g || !b || !out1 || !out2)
45 goto fail;
46
47 if (winpr_RAND(r, 1ULL * rgbStride * roi.height) < 0)
48 goto fail;
49 if (winpr_RAND(g, 1ULL * rgbStride * roi.height) < 0)
50 goto fail;
51 if (winpr_RAND(b, 1ULL * rgbStride * roi.height) < 0)
52 goto fail;
53 ptrs[0] = r;
54 ptrs[1] = g;
55 ptrs[2] = b;
56 PROFILER_ENTER(genericProf)
57
58 if (generic->RGBToRGB_16s8u_P3AC4R(ptrs, rgbStride, out1, dstStride, DstFormat, &roi) !=
59 PRIMITIVES_SUCCESS)
60 goto fail;
61
62 PROFILER_EXIT(genericProf)
63 PROFILER_ENTER(optProf)
64
65 if (optimized->RGBToRGB_16s8u_P3AC4R(ptrs, rgbStride, out2, dstStride, DstFormat, &roi) !=
66 PRIMITIVES_SUCCESS)
67 goto fail;
68
69 PROFILER_EXIT(optProf)
70
71 if (memcmp(out1, out2, 1ULL * dstStride * roi.height) != 0)
72 {
73 for (UINT64 i = 0; i < 1ull * roi.width * roi.height; ++i)
74 {
75 const UINT32 o1 = FreeRDPReadColor(out1 + 4 * i, DstFormat);
76 const UINT32 o2 = FreeRDPReadColor(out2 + 4 * i, DstFormat);
77
78 if (o1 != o2)
79 {
80 printf("RGBToRGB_16s8u_P3AC4R FAIL: out1[%" PRIu64 "]=0x%08" PRIx8 " out2[%" PRIu64
81 "]=0x%08" PRIx8 "\n",
82 i, out1[i], i, out2[i]);
83 failed = TRUE;
84 }
85 }
86 }
87
88 printf("Results for %" PRIu32 "x%" PRIu32 " [%s]\n", roi.width, roi.height,
89 FreeRDPGetColorFormatName(DstFormat));
90 PROFILER_PRINT_HEADER
91 PROFILER_PRINT(genericProf)
92 PROFILER_PRINT(optProf)
93 PROFILER_PRINT_FOOTER
94fail:
95 PROFILER_FREE(genericProf)
96 PROFILER_FREE(optProf)
97 winpr_aligned_free(r);
98 winpr_aligned_free(g);
99 winpr_aligned_free(b);
100 winpr_aligned_free(out1);
101 winpr_aligned_free(out2);
102 return !failed;
103}
104
105/* ------------------------------------------------------------------------- */
106static BOOL test_RGBToRGB_16s8u_P3AC4R_speed(void)
107{
108 union
109 {
110 const INT16** cpv;
111 INT16** pv;
112 } cnv;
113 const prim_size_t roi64x64 = { 64, 64 };
114 INT16 r[4096 + 1] = WINPR_C_ARRAY_INIT;
115 INT16 g[4096 + 1] = WINPR_C_ARRAY_INIT;
116 INT16 b[4096 + 1] = WINPR_C_ARRAY_INIT;
117 UINT32 dst[4096 + 1] = WINPR_C_ARRAY_INIT;
118 INT16* ptrs[3] = WINPR_C_ARRAY_INIT;
119 if (winpr_RAND(r, sizeof(r)) < 0)
120 return FALSE;
121 if (winpr_RAND(g, sizeof(g)) < 0)
122 return FALSE;
123 if (winpr_RAND(b, sizeof(b)) < 0)
124 return FALSE;
125
126 /* clear upper bytes */
127 for (int i = 0; i < 4096; ++i)
128 {
129 r[i] &= 0x00FFU;
130 g[i] &= 0x00FFU;
131 b[i] &= 0x00FFU;
132 }
133
134 ptrs[0] = r + 1;
135 ptrs[1] = g + 1;
136 ptrs[2] = b + 1;
137
138 cnv.pv = ptrs;
139 if (!speed_test("RGBToRGB_16s8u_P3AC4R", "aligned", g_Iterations,
140 (speed_test_fkt)generic->RGBToRGB_16s8u_P3AC4R,
141 (speed_test_fkt)optimized->RGBToRGB_16s8u_P3AC4R, cnv.cpv, 64 * 2, (BYTE*)dst,
142 64 * 4, &roi64x64))
143 return FALSE;
144
145 if (!speed_test("RGBToRGB_16s8u_P3AC4R", "unaligned", g_Iterations,
146 (speed_test_fkt)generic->RGBToRGB_16s8u_P3AC4R,
147 (speed_test_fkt)optimized->RGBToRGB_16s8u_P3AC4R, cnv.cpv, 64 * 2,
148 ((BYTE*)dst) + 1, 64 * 4, &roi64x64))
149 return FALSE;
150
151 return TRUE;
152}
153
154/* ========================================================================= */
155static BOOL test_yCbCrToRGB_16s16s_P3P3_func(void)
156{
157 pstatus_t status = 0;
158 INT16 y[4096] = WINPR_C_ARRAY_INIT;
159 INT16 cb[4096] = WINPR_C_ARRAY_INIT;
160 INT16 cr[4096] = WINPR_C_ARRAY_INIT;
161 INT16 r1[4096] = WINPR_C_ARRAY_INIT;
162 INT16 g1[4096] = WINPR_C_ARRAY_INIT;
163 INT16 b1[4096] = WINPR_C_ARRAY_INIT;
164 INT16 r2[4096] = WINPR_C_ARRAY_INIT;
165 INT16 g2[4096] = WINPR_C_ARRAY_INIT;
166 INT16 b2[4096] = WINPR_C_ARRAY_INIT;
167 const INT16* in[3];
168 INT16* out1[3];
169 INT16* out2[3];
170 prim_size_t roi = { 64, 64 };
171 if (winpr_RAND(y, sizeof(y)) < 0)
172 return FALSE;
173 if (winpr_RAND(cb, sizeof(cb)) < 0)
174 return FALSE;
175 if (winpr_RAND(cr, sizeof(cr)) < 0)
176 return FALSE;
177
178 /* Normalize to 11.5 fixed radix */
179 for (int i = 0; i < 4096; ++i)
180 {
181 y[i] &= 0x1FE0U;
182 cb[i] &= 0x1FE0U;
183 cr[i] &= 0x1FE0U;
184 }
185
186 in[0] = y;
187 in[1] = cb;
188 in[2] = cr;
189 out1[0] = r1;
190 out1[1] = g1;
191 out1[2] = b1;
192 out2[0] = r2;
193 out2[1] = g2;
194 out2[2] = b2;
195 status = generic->yCbCrToRGB_16s16s_P3P3(in, 64 * 2, out1, 64 * 2, &roi);
196
197 if (status != PRIMITIVES_SUCCESS)
198 return FALSE;
199
200 status = optimized->yCbCrToRGB_16s16s_P3P3(in, 64 * 2, out2, 64 * 2, &roi);
201
202 if (status != PRIMITIVES_SUCCESS)
203 return FALSE;
204
205 for (int i = 0; i < 4096; ++i)
206 {
207 if ((ABS(r1[i] - r2[i]) > 1) || (ABS(g1[i] - g2[i]) > 1) || (ABS(b1[i] - b2[i]) > 1))
208 {
209 printf("YCbCrToRGB-SSE FAIL[%d]: %" PRId16 ",%" PRId16 ",%" PRId16 " vs %" PRId16
210 ",%" PRId16 ",%" PRId16 "\n",
211 i, r1[i], g1[i], b1[i], r2[i], g2[i], b2[i]);
212 return FALSE;
213 }
214 }
215
216 return TRUE;
217}
218
219/* ------------------------------------------------------------------------- */
220static int test_yCbCrToRGB_16s16s_P3P3_speed(void)
221{
222 prim_size_t roi = { 64, 64 };
223 INT16 y[4096] = WINPR_C_ARRAY_INIT;
224 INT16 cb[4096] = WINPR_C_ARRAY_INIT;
225 INT16 cr[4096] = WINPR_C_ARRAY_INIT;
226 INT16 r[4096] = WINPR_C_ARRAY_INIT;
227 INT16 g[4096] = WINPR_C_ARRAY_INIT;
228 INT16 b[4096] = WINPR_C_ARRAY_INIT;
229 const INT16* input[3] = WINPR_C_ARRAY_INIT;
230 INT16* output[3] = WINPR_C_ARRAY_INIT;
231 if (winpr_RAND(y, sizeof(y)) < 0)
232 return FALSE;
233 if (winpr_RAND(cb, sizeof(cb)) < 0)
234 return FALSE;
235 if (winpr_RAND(cr, sizeof(cr)) < 0)
236 return FALSE;
237
238 /* Normalize to 11.5 fixed radix */
239 for (int i = 0; i < 4096; ++i)
240 {
241 y[i] &= 0x1FE0U;
242 cb[i] &= 0x1FE0U;
243 cr[i] &= 0x1FE0U;
244 }
245
246 input[0] = y;
247 input[1] = cb;
248 input[2] = cr;
249 output[0] = r;
250 output[1] = g;
251 output[2] = b;
252
253 return (speed_test("yCbCrToRGB_16s16s_P3P3", "aligned", g_Iterations,
254 (speed_test_fkt)generic->yCbCrToRGB_16s16s_P3P3,
255 (speed_test_fkt)optimized->yCbCrToRGB_16s16s_P3P3, input, 64 * 2, output,
256 64 * 2, &roi));
257}
258
259int TestPrimitivesColors(int argc, char* argv[])
260{
261 const DWORD formats[] = { PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_XRGB32, PIXEL_FORMAT_ABGR32,
262 PIXEL_FORMAT_XBGR32, PIXEL_FORMAT_RGBA32, PIXEL_FORMAT_RGBX32,
263 PIXEL_FORMAT_BGRA32, PIXEL_FORMAT_BGRX32 };
264 prim_size_t roi = { 1920 / 4, 1080 / 4 };
265 WINPR_UNUSED(argc);
266 WINPR_UNUSED(argv);
267 prim_test_setup(FALSE);
268
269 for (UINT32 x = 0; x < sizeof(formats) / sizeof(formats[0]); x++)
270 {
271 if (!test_RGBToRGB_16s8u_P3AC4R_func(roi, formats[x]))
272 return 1;
273
274 if (g_TestPrimitivesPerformance)
275 {
276 if (!test_RGBToRGB_16s8u_P3AC4R_speed())
277 return 1;
278 }
279
280 if (!test_yCbCrToRGB_16s16s_P3P3_func())
281 return 1;
282
283 if (g_TestPrimitivesPerformance)
284 {
285 if (!test_yCbCrToRGB_16s16s_P3P3_speed())
286 return 1;
287 }
288 }
289
290 return 0;
291}