17 #ifndef FREERDP_LIB_PRIM_INTERNAL_H
18 #define FREERDP_LIB_PRIM_INTERNAL_H
20 #include <winpr/platform.h>
21 #include <freerdp/config.h>
23 #include <freerdp/primitives.h>
24 #include <freerdp/api.h>
26 #include <freerdp/log.h>
28 #include "../core/simd.h"
30 #define PRIM_TAG FREERDP_TAG("primitives")
33 #define PRIM_ALIGN_128 __attribute__((aligned(16)))
36 #define PRIM_ALIGN_128 __declspec(align(16))
40 #if defined(SSE_AVX_INTRINSICS_ENABLED) || defined(NEON_INTRINSICS_ENABLED) || defined(WITH_OPENCL)
41 #define HAVE_OPTIMIZED_PRIMITIVES 1
44 #if defined(SSE_AVX_INTRINSICS_ENABLED) || defined(NEON_INTRINSICS_ENABLED)
45 #define HAVE_CPU_OPTIMIZED_PRIMITIVES 1
48 #if defined(SSE_AVX_INTRINSICS_ENABLED)
49 #include <emmintrin.h>
50 static inline __m128i mm_set_epu32(uint32_t val1, uint32_t val2, uint32_t val3, uint32_t val4)
52 return _mm_set_epi32((int32_t)val1, (int32_t)val2, (int32_t)val3, (int32_t)val4);
55 static inline __m128i mm_set1_epu32(uint32_t val)
57 return _mm_set1_epi32((int32_t)val);
60 static inline __m128i mm_set1_epu8(uint8_t val)
62 return _mm_set1_epi8((int8_t)val);
66 #define LOAD_SI128(_ptr_) \
67 (((const ULONG_PTR)(_ptr_)&0x0f) ? _mm_lddqu_si128((const __m128i*)(_ptr_)) \
68 : _mm_load_si128((const __m128i*)(_ptr_)))
71 static INLINE BYTE* writePixelBGRA(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
74 WINPR_UNUSED(formatSize);
84 static INLINE BYTE* writePixelBGRX(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
87 WINPR_UNUSED(formatSize);
99 static INLINE BYTE* writePixelRGBA(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
102 WINPR_UNUSED(formatSize);
103 WINPR_UNUSED(format);
112 static INLINE BYTE* writePixelRGBX(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
115 WINPR_UNUSED(formatSize);
116 WINPR_UNUSED(format);
127 static INLINE BYTE* writePixelABGR(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
130 WINPR_UNUSED(formatSize);
131 WINPR_UNUSED(format);
140 static INLINE BYTE* writePixelXBGR(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
143 WINPR_UNUSED(formatSize);
144 WINPR_UNUSED(format);
154 static INLINE BYTE* writePixelARGB(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
157 WINPR_UNUSED(formatSize);
158 WINPR_UNUSED(format);
167 static INLINE BYTE* writePixelXRGB(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
170 WINPR_UNUSED(formatSize);
171 WINPR_UNUSED(format);
181 static INLINE BYTE* writePixelGenericAlpha(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R,
182 BYTE G, BYTE B, BYTE A)
184 UINT32 color = FreeRDPGetColor(format, R, G, B, A);
185 FreeRDPWriteColor(dst, format, color);
186 return dst + formatSize;
189 static INLINE BYTE* writePixelGeneric(BYTE* dst, DWORD formatSize, UINT32 format, BYTE R, BYTE G,
192 UINT32 color = FreeRDPGetColor(format, R, G, B, A);
193 FreeRDPWriteColorIgnoreAlpha(dst, format, color);
194 return dst + formatSize;
197 typedef BYTE* (*fkt_writePixel)(BYTE*, DWORD, UINT32, BYTE, BYTE, BYTE, BYTE);
199 static INLINE fkt_writePixel getPixelWriteFunction(DWORD format, BOOL useAlpha)
203 case PIXEL_FORMAT_ARGB32:
204 case PIXEL_FORMAT_XRGB32:
205 return useAlpha ? writePixelARGB : writePixelXRGB;
207 case PIXEL_FORMAT_ABGR32:
208 case PIXEL_FORMAT_XBGR32:
209 return useAlpha ? writePixelABGR : writePixelXBGR;
211 case PIXEL_FORMAT_RGBA32:
212 case PIXEL_FORMAT_RGBX32:
213 return useAlpha ? writePixelRGBA : writePixelRGBX;
215 case PIXEL_FORMAT_BGRA32:
216 case PIXEL_FORMAT_BGRX32:
217 return useAlpha ? writePixelBGRA : writePixelBGRX;
220 return useAlpha ? writePixelGenericAlpha : writePixelGeneric;
224 static INLINE BYTE CLIP(INT64 X)
235 static INLINE BYTE CONDITIONAL_CLIP(INT32 in, BYTE original)
240 diff = out - original;
242 diff = original - out;
253 static INLINE INT32 C(INT32 Y)
258 static INLINE INT32 D(INT32 U)
263 static INLINE INT32 E(INT32 V)
268 static INLINE BYTE YUV2R(INT32 Y, INT32 U, INT32 V)
270 const INT32 r = (256L * C(Y) + 0L * D(U) + 403L * E(V));
271 const INT32 r8 = r >> 8L;
275 static INLINE BYTE YUV2G(INT32 Y, INT32 U, INT32 V)
277 const INT32 g = (256L * C(Y) - 48L * D(U) - 120L * E(V));
278 const INT32 g8 = g >> 8L;
282 static INLINE BYTE YUV2B(INT32 Y, INT32 U, INT32 V)
284 const INT32 b = (256L * C(Y) + 475L * D(U) + 0L * E(V));
285 const INT32 b8 = b >> 8L;
290 FREERDP_LOCAL
void primitives_init_copy(
primitives_t* WINPR_RESTRICT prims);
291 FREERDP_LOCAL
void primitives_init_set(
primitives_t* WINPR_RESTRICT prims);
292 FREERDP_LOCAL
void primitives_init_add(
primitives_t* WINPR_RESTRICT prims);
293 FREERDP_LOCAL
void primitives_init_andor(
primitives_t* WINPR_RESTRICT prims);
294 FREERDP_LOCAL
void primitives_init_shift(
primitives_t* WINPR_RESTRICT prims);
295 FREERDP_LOCAL
void primitives_init_sign(
primitives_t* WINPR_RESTRICT prims);
296 FREERDP_LOCAL
void primitives_init_alphaComp(
primitives_t* WINPR_RESTRICT prims);
297 FREERDP_LOCAL
void primitives_init_colors(
primitives_t* WINPR_RESTRICT prims);
298 FREERDP_LOCAL
void primitives_init_YCoCg(
primitives_t* WINPR_RESTRICT prims);
299 FREERDP_LOCAL
void primitives_init_YUV(
primitives_t* WINPR_RESTRICT prims);
301 FREERDP_LOCAL
void primitives_init_copy_opt(
primitives_t* WINPR_RESTRICT prims);
302 FREERDP_LOCAL
void primitives_init_set_opt(
primitives_t* WINPR_RESTRICT prims);
303 FREERDP_LOCAL
void primitives_init_add_opt(
primitives_t* WINPR_RESTRICT prims);
304 FREERDP_LOCAL
void primitives_init_andor_opt(
primitives_t* WINPR_RESTRICT prims);
305 FREERDP_LOCAL
void primitives_init_shift_opt(
primitives_t* WINPR_RESTRICT prims);
306 FREERDP_LOCAL
void primitives_init_sign_opt(
primitives_t* WINPR_RESTRICT prims);
307 FREERDP_LOCAL
void primitives_init_alphaComp_opt(
primitives_t* WINPR_RESTRICT prims);
308 FREERDP_LOCAL
void primitives_init_colors_opt(
primitives_t* WINPR_RESTRICT prims);
309 FREERDP_LOCAL
void primitives_init_YCoCg_opt(
primitives_t* WINPR_RESTRICT prims);
310 FREERDP_LOCAL
void primitives_init_YUV_opt(
primitives_t* WINPR_RESTRICT prims);
312 #if defined(WITH_OPENCL)
313 FREERDP_LOCAL BOOL primitives_init_opencl(
primitives_t* WINPR_RESTRICT prims);
316 FREERDP_LOCAL
primitives_t* primitives_get_by_type(DWORD type);