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