FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
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 = NULL;
26 INT16* g = NULL;
27 INT16* b = NULL;
28 BYTE* out1 = NULL;
29 BYTE* out2 = NULL;
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 winpr_RAND(r, 1ULL * rgbStride * roi.height);
48 winpr_RAND(g, 1ULL * rgbStride * roi.height);
49 winpr_RAND(b, 1ULL * rgbStride * roi.height);
50 ptrs[0] = r;
51 ptrs[1] = g;
52 ptrs[2] = b;
53 PROFILER_ENTER(genericProf)
54
55 if (generic->RGBToRGB_16s8u_P3AC4R(ptrs, rgbStride, out1, dstStride, DstFormat, &roi) !=
56 PRIMITIVES_SUCCESS)
57 goto fail;
58
59 PROFILER_EXIT(genericProf)
60 PROFILER_ENTER(optProf)
61
62 if (optimized->RGBToRGB_16s8u_P3AC4R(ptrs, rgbStride, out2, dstStride, DstFormat, &roi) !=
63 PRIMITIVES_SUCCESS)
64 goto fail;
65
66 PROFILER_EXIT(optProf)
67
68 if (memcmp(out1, out2, 1ULL * dstStride * roi.height) != 0)
69 {
70 for (UINT64 i = 0; i < 1ull * roi.width * roi.height; ++i)
71 {
72 const UINT32 o1 = FreeRDPReadColor(out1 + 4 * i, DstFormat);
73 const UINT32 o2 = FreeRDPReadColor(out2 + 4 * i, DstFormat);
74
75 if (o1 != o2)
76 {
77 printf("RGBToRGB_16s8u_P3AC4R FAIL: out1[%" PRIu64 "]=0x%08" PRIx8 " out2[%" PRIu64
78 "]=0x%08" PRIx8 "\n",
79 i, out1[i], i, out2[i]);
80 failed = TRUE;
81 }
82 }
83 }
84
85 printf("Results for %" PRIu32 "x%" PRIu32 " [%s]\n", roi.width, roi.height,
86 FreeRDPGetColorFormatName(DstFormat));
87 PROFILER_PRINT_HEADER
88 PROFILER_PRINT(genericProf)
89 PROFILER_PRINT(optProf)
90 PROFILER_PRINT_FOOTER
91fail:
92 PROFILER_FREE(genericProf)
93 PROFILER_FREE(optProf)
94 winpr_aligned_free(r);
95 winpr_aligned_free(g);
96 winpr_aligned_free(b);
97 winpr_aligned_free(out1);
98 winpr_aligned_free(out2);
99 return !failed;
100}
101
102/* ------------------------------------------------------------------------- */
103static BOOL test_RGBToRGB_16s8u_P3AC4R_speed(void)
104{
105 union
106 {
107 const INT16** cpv;
108 INT16** pv;
109 } cnv;
110 const prim_size_t roi64x64 = { 64, 64 };
111 INT16 ALIGN(r[4096 + 1]);
112 INT16 ALIGN(g[4096 + 1]);
113 INT16 ALIGN(b[4096 + 1]);
114 UINT32 ALIGN(dst[4096 + 1]);
115 INT16* ptrs[3];
116 winpr_RAND(r, sizeof(r));
117 winpr_RAND(g, sizeof(g));
118 winpr_RAND(b, sizeof(b));
119
120 /* clear upper bytes */
121 for (int i = 0; i < 4096; ++i)
122 {
123 r[i] &= 0x00FFU;
124 g[i] &= 0x00FFU;
125 b[i] &= 0x00FFU;
126 }
127
128 ptrs[0] = r + 1;
129 ptrs[1] = g + 1;
130 ptrs[2] = b + 1;
131
132 cnv.pv = ptrs;
133 if (!speed_test("RGBToRGB_16s8u_P3AC4R", "aligned", g_Iterations,
134 (speed_test_fkt)generic->RGBToRGB_16s8u_P3AC4R,
135 (speed_test_fkt)optimized->RGBToRGB_16s8u_P3AC4R, cnv.cpv, 64 * 2, (BYTE*)dst,
136 64 * 4, &roi64x64))
137 return FALSE;
138
139 if (!speed_test("RGBToRGB_16s8u_P3AC4R", "unaligned", g_Iterations,
140 (speed_test_fkt)generic->RGBToRGB_16s8u_P3AC4R,
141 (speed_test_fkt)optimized->RGBToRGB_16s8u_P3AC4R, cnv.cpv, 64 * 2,
142 ((BYTE*)dst) + 1, 64 * 4, &roi64x64))
143 return FALSE;
144
145 return TRUE;
146}
147
148/* ========================================================================= */
149static BOOL test_yCbCrToRGB_16s16s_P3P3_func(void)
150{
151 pstatus_t status = 0;
152 INT16 ALIGN(y[4096]) = { 0 };
153 INT16 ALIGN(cb[4096]) = { 0 };
154 INT16 ALIGN(cr[4096]) = { 0 };
155 INT16 ALIGN(r1[4096]) = { 0 };
156 INT16 ALIGN(g1[4096]) = { 0 };
157 INT16 ALIGN(b1[4096]) = { 0 };
158 INT16 ALIGN(r2[4096]) = { 0 };
159 INT16 ALIGN(g2[4096]) = { 0 };
160 INT16 ALIGN(b2[4096]) = { 0 };
161 const INT16* in[3];
162 INT16* out1[3];
163 INT16* out2[3];
164 prim_size_t roi = { 64, 64 };
165 winpr_RAND(y, sizeof(y));
166 winpr_RAND(cb, sizeof(cb));
167 winpr_RAND(cr, sizeof(cr));
168
169 /* Normalize to 11.5 fixed radix */
170 for (int i = 0; i < 4096; ++i)
171 {
172 y[i] &= 0x1FE0U;
173 cb[i] &= 0x1FE0U;
174 cr[i] &= 0x1FE0U;
175 }
176
177 in[0] = y;
178 in[1] = cb;
179 in[2] = cr;
180 out1[0] = r1;
181 out1[1] = g1;
182 out1[2] = b1;
183 out2[0] = r2;
184 out2[1] = g2;
185 out2[2] = b2;
186 status = generic->yCbCrToRGB_16s16s_P3P3(in, 64 * 2, out1, 64 * 2, &roi);
187
188 if (status != PRIMITIVES_SUCCESS)
189 return FALSE;
190
191 status = optimized->yCbCrToRGB_16s16s_P3P3(in, 64 * 2, out2, 64 * 2, &roi);
192
193 if (status != PRIMITIVES_SUCCESS)
194 return FALSE;
195
196 for (int i = 0; i < 4096; ++i)
197 {
198 if ((ABS(r1[i] - r2[i]) > 1) || (ABS(g1[i] - g2[i]) > 1) || (ABS(b1[i] - b2[i]) > 1))
199 {
200 printf("YCbCrToRGB-SSE FAIL[%d]: %" PRId16 ",%" PRId16 ",%" PRId16 " vs %" PRId16
201 ",%" PRId16 ",%" PRId16 "\n",
202 i, r1[i], g1[i], b1[i], r2[i], g2[i], b2[i]);
203 return FALSE;
204 }
205 }
206
207 return TRUE;
208}
209
210/* ------------------------------------------------------------------------- */
211static int test_yCbCrToRGB_16s16s_P3P3_speed(void)
212{
213 prim_size_t roi = { 64, 64 };
214 INT16 ALIGN(y[4096]);
215 INT16 ALIGN(cb[4096]);
216 INT16 ALIGN(cr[4096]);
217 INT16 ALIGN(r[4096]);
218 INT16 ALIGN(g[4096]);
219 INT16 ALIGN(b[4096]);
220 const INT16* input[3];
221 INT16* output[3];
222 winpr_RAND(y, sizeof(y));
223 winpr_RAND(cb, sizeof(cb));
224 winpr_RAND(cr, sizeof(cr));
225
226 /* Normalize to 11.5 fixed radix */
227 for (int i = 0; i < 4096; ++i)
228 {
229 y[i] &= 0x1FE0U;
230 cb[i] &= 0x1FE0U;
231 cr[i] &= 0x1FE0U;
232 }
233
234 input[0] = y;
235 input[1] = cb;
236 input[2] = cr;
237 output[0] = r;
238 output[1] = g;
239 output[2] = b;
240
241 if (!speed_test("yCbCrToRGB_16s16s_P3P3", "aligned", g_Iterations,
242 (speed_test_fkt)generic->yCbCrToRGB_16s16s_P3P3,
243 (speed_test_fkt)optimized->yCbCrToRGB_16s16s_P3P3, input, 64 * 2, output,
244 64 * 2, &roi))
245 return FALSE;
246
247 return TRUE;
248}
249
250int TestPrimitivesColors(int argc, char* argv[])
251{
252 const DWORD formats[] = { PIXEL_FORMAT_ARGB32, PIXEL_FORMAT_XRGB32, PIXEL_FORMAT_ABGR32,
253 PIXEL_FORMAT_XBGR32, PIXEL_FORMAT_RGBA32, PIXEL_FORMAT_RGBX32,
254 PIXEL_FORMAT_BGRA32, PIXEL_FORMAT_BGRX32 };
255 prim_size_t roi = { 1920 / 4, 1080 / 4 };
256 WINPR_UNUSED(argc);
257 WINPR_UNUSED(argv);
258 prim_test_setup(FALSE);
259
260 for (UINT32 x = 0; x < sizeof(formats) / sizeof(formats[0]); x++)
261 {
262 if (!test_RGBToRGB_16s8u_P3AC4R_func(roi, formats[x]))
263 return 1;
264
265 if (g_TestPrimitivesPerformance)
266 {
267 if (!test_RGBToRGB_16s8u_P3AC4R_speed())
268 return 1;
269 }
270
271 if (!test_yCbCrToRGB_16s16s_P3P3_func())
272 return 1;
273
274 if (g_TestPrimitivesPerformance)
275 {
276 if (!test_yCbCrToRGB_16s16s_P3P3_speed())
277 return 1;
278 }
279 }
280
281 return 0;
282}