Merge branch 'master' of github.com:FreeRDP/FreeRDP

This commit is contained in:
Marc-André Moreau 2013-03-04 16:07:29 -05:00
commit cd7edbbc81
64 changed files with 1494 additions and 712 deletions

View File

@ -303,6 +303,7 @@ if(ANDROID)
set(GSTREAMER_FEATURE_TYPE "DISABLED") set(GSTREAMER_FEATURE_TYPE "DISABLED")
endif() endif()
find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION}) find_feature(X11 ${X11_FEATURE_TYPE} ${X11_FEATURE_PURPOSE} ${X11_FEATURE_DESCRIPTION})
find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION}) find_feature(DirectFB ${DIRECTFB_FEATURE_TYPE} ${DIRECTFB_FEATURE_PURPOSE} ${DIRECTFB_FEATURE_DESCRIPTION})
@ -318,8 +319,12 @@ find_feature(PCSC ${PCSC_FEATURE_TYPE} ${PCSC_FEATURE_PURPOSE} ${PCSC_FEATURE_DE
find_feature(FFmpeg ${FFMPEG_FEATURE_TYPE} ${FFMPEG_FEATURE_PURPOSE} ${FFMPEG_FEATURE_DESCRIPTION}) find_feature(FFmpeg ${FFMPEG_FEATURE_TYPE} ${FFMPEG_FEATURE_PURPOSE} ${FFMPEG_FEATURE_DESCRIPTION})
find_feature(Gstreamer ${GSTREAMER_FEATURE_TYPE} ${GSTREAMER_FEATURE_PURPOSE} ${GSTREAMER_FEATURE_DESCRIPTION}) find_feature(Gstreamer ${GSTREAMER_FEATURE_TYPE} ${GSTREAMER_FEATURE_PURPOSE} ${GSTREAMER_FEATURE_DESCRIPTION})
# Intel Performance Primitives if(TARGET_ARCH MATCHES "x86|x64")
find_feature(IPP ${IPP_FEATURE_TYPE} ${IPP_FEATURE_PURPOSE} ${IPP_FEATURE_DESCRIPTION}) if (NOT APPLE)
# Intel Performance Primitives
find_feature(IPP ${IPP_FEATURE_TYPE} ${IPP_FEATURE_PURPOSE} ${IPP_FEATURE_DESCRIPTION})
endif()
endif()
# Installation Paths # Installation Paths
if(WIN32) if(WIN32)

View File

@ -306,44 +306,6 @@ BOOL wf_pre_connect(freerdp* instance)
return TRUE; return TRUE;
} }
void cpuid(unsigned info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
{
#if defined(__GNUC__)
#if defined(__i386__) || defined(__x86_64__)
*eax = info;
__asm volatile
("mov %%ebx, %%edi;" /* 32bit PIC: don't clobber ebx */
"cpuid;"
"mov %%ebx, %%esi;"
"mov %%edi, %%ebx;"
:"+a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
: :"edi");
#endif
#elif defined(_MSC_VER)
int a[4];
__cpuid(a, info);
*eax = a[0];
*ebx = a[1];
*ecx = a[2];
*edx = a[3];
#endif
}
UINT32 wfi_detect_cpu()
{
UINT32 cpu_opt = 0;
unsigned int eax, ebx, ecx, edx = 0;
cpuid(1, &eax, &ebx, &ecx, &edx);
if (edx & (1<<26))
{
cpu_opt |= CPU_SSE2;
}
return cpu_opt;
}
BOOL wf_post_connect(freerdp* instance) BOOL wf_post_connect(freerdp* instance)
{ {
rdpGdi* gdi; rdpGdi* gdi;
@ -368,8 +330,6 @@ BOOL wf_post_connect(freerdp* instance)
gdi = instance->context->gdi; gdi = instance->context->gdi;
wfi->hdc = gdi->primary->hdc; wfi->hdc = gdi->primary->hdc;
wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, gdi->primary_buffer); wfi->primary = wf_image_new(wfi, wfi->width, wfi->height, wfi->dstBpp, gdi->primary_buffer);
rfx_context_set_cpu_opt((RFX_CONTEXT*) gdi->rfx_context, wfi_detect_cpu());
} }
else else
{ {
@ -396,7 +356,6 @@ BOOL wf_post_connect(freerdp* instance)
{ {
wfi->tile = wf_image_new(wfi, 64, 64, 32, NULL); wfi->tile = wf_image_new(wfi, 64, 64, 32, NULL);
wfi->rfx_context = rfx_context_new(); wfi->rfx_context = rfx_context_new();
rfx_context_set_cpu_opt(wfi->rfx_context, wfi_detect_cpu());
} }
if (settings->NSCodec) if (settings->NSCodec)

View File

@ -391,7 +391,7 @@ void xf_create_window(xfInfo* xfi)
xfi->attribs.background_pixel = BlackPixelOfScreen(xfi->screen); xfi->attribs.background_pixel = BlackPixelOfScreen(xfi->screen);
xfi->attribs.border_pixel = WhitePixelOfScreen(xfi->screen); xfi->attribs.border_pixel = WhitePixelOfScreen(xfi->screen);
xfi->attribs.backing_store = xfi->primary ? NotUseful : Always; xfi->attribs.backing_store = xfi->primary ? NotUseful : Always;
xfi->attribs.override_redirect = xfi->fullscreen; xfi->attribs.override_redirect = xfi->grab_keyboard ? xfi->fullscreen : False;
xfi->attribs.colormap = xfi->colormap; xfi->attribs.colormap = xfi->colormap;
xfi->attribs.bit_gravity = NorthWestGravity; xfi->attribs.bit_gravity = NorthWestGravity;
xfi->attribs.win_gravity = NorthWestGravity; xfi->attribs.win_gravity = NorthWestGravity;
@ -753,7 +753,7 @@ BOOL xf_pre_connect(freerdp* instance)
xfi->decorations = settings->Decorations; xfi->decorations = settings->Decorations;
xfi->fullscreen = settings->Fullscreen; xfi->fullscreen = settings->Fullscreen;
xfi->grab_keyboard = settings->GrabKeyboard; xfi->grab_keyboard = settings->GrabKeyboard;
xfi->fullscreen_toggle = TRUE; xfi->fullscreen_toggle = settings->ToggleFullscreen;
xfi->sw_gdi = settings->SoftwareGdi; xfi->sw_gdi = settings->SoftwareGdi;
xfi->parent_window = (Window) settings->ParentWindowId; xfi->parent_window = (Window) settings->ParentWindowId;
@ -762,46 +762,6 @@ BOOL xf_pre_connect(freerdp* instance)
return TRUE; return TRUE;
} }
void cpuid(unsigned info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx)
{
#ifdef __GNUC__
#if defined(__i386__) || defined(__x86_64__)
__asm volatile
(
/* The EBX (or RBX register on x86_64) is used for the PIC base address
and must not be corrupted by our inline assembly. */
#if defined(__i386__)
"mov %%ebx, %%esi;"
"cpuid;"
"xchg %%ebx, %%esi;"
#else
"mov %%rbx, %%rsi;"
"cpuid;"
"xchg %%rbx, %%rsi;"
#endif
: "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (info)
);
#endif
#endif
}
UINT32 xf_detect_cpu()
{
unsigned int eax, ebx, ecx, edx = 0;
UINT32 cpu_opt = 0;
cpuid(1, &eax, &ebx, &ecx, &edx);
if (edx & (1<<26))
{
DEBUG_MSG("SSE2 detected");
cpu_opt |= CPU_SSE2;
}
return cpu_opt;
}
/** /**
* Callback given to freerdp_connect() to perform post-connection operations. * Callback given to freerdp_connect() to perform post-connection operations.
* It will be called only if the connection was initialized properly, and will continue the initialization based on the * It will be called only if the connection was initialized properly, and will continue the initialization based on the
@ -809,9 +769,6 @@ UINT32 xf_detect_cpu()
*/ */
BOOL xf_post_connect(freerdp* instance) BOOL xf_post_connect(freerdp* instance)
{ {
#ifdef WITH_SSE2
UINT32 cpu;
#endif
xfInfo* xfi; xfInfo* xfi;
XGCValues gcv; XGCValues gcv;
rdpCache* cache; rdpCache* cache;
@ -866,15 +823,6 @@ BOOL xf_post_connect(freerdp* instance)
} }
} }
#ifdef WITH_SSE2
/* detect only if needed */
cpu = xf_detect_cpu();
if (rfx_context)
rfx_context_set_cpu_opt(rfx_context, cpu);
if (nsc_context)
nsc_context_set_cpu_opt(nsc_context, cpu);
#endif
xfi->width = instance->settings->DesktopWidth; xfi->width = instance->settings->DesktopWidth;
xfi->height = instance->settings->DesktopHeight; xfi->height = instance->settings->DesktopHeight;

View File

@ -112,6 +112,7 @@ COMMAND_LINE_ARGUMENT_A args[] =
{ "authentication", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "authentication (hack!)" }, { "authentication", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "authentication (hack!)" },
{ "encryption", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "encryption (hack!)" }, { "encryption", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "encryption (hack!)" },
{ "grab-keyboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "grab keyboard" }, { "grab-keyboard", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "grab keyboard" },
{ "toggle-fullscreen", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Alt+Ctrl+Enter toggles fullscreen" },
{ "mouse-motion", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "mouse-motion" }, { "mouse-motion", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "mouse-motion" },
{ "parent-window", COMMAND_LINE_VALUE_REQUIRED, "<window id>", NULL, NULL, -1, NULL, "Parent window id" }, { "parent-window", COMMAND_LINE_VALUE_REQUIRED, "<window id>", NULL, NULL, -1, NULL, "Parent window id" },
{ "bitmap-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "bitmap cache" }, { "bitmap-cache", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "bitmap cache" },
@ -1438,6 +1439,10 @@ int freerdp_client_parse_command_line_arguments(int argc, char** argv, rdpSettin
{ {
settings->GrabKeyboard = arg->Value ? TRUE : FALSE; settings->GrabKeyboard = arg->Value ? TRUE : FALSE;
} }
CommandLineSwitchCase(arg, "toggle-fullscreen")
{
settings->ToggleFullscreen = arg->Value ? TRUE : FALSE;
}
CommandLineSwitchCase(arg, "mouse-motion") CommandLineSwitchCase(arg, "mouse-motion")
{ {
settings->MouseMotion = arg->Value ? TRUE : FALSE; settings->MouseMotion = arg->Value ? TRUE : FALSE;

View File

@ -9,7 +9,6 @@ endif()
option(WITH_MANPAGES "Generate manpages." ON) option(WITH_MANPAGES "Generate manpages." ON)
option(WITH_PROFILER "Compile profiler." OFF) option(WITH_PROFILER "Compile profiler." OFF)
option(WITH_IPP "Use Intel Performance Primitives." OFF)
if((TARGET_ARCH MATCHES "x86|x64") AND (NOT DEFINED WITH_SSE2)) if((TARGET_ARCH MATCHES "x86|x64") AND (NOT DEFINED WITH_SSE2))
option(WITH_SSE2 "Enable SSE2 optimization." ON) option(WITH_SSE2 "Enable SSE2 optimization." ON)
@ -29,8 +28,11 @@ if(TARGET_ARCH MATCHES "ARM")
set(ARM_FP_ABI ${ARM_FP_API} CACHE STRING "Floating point ABI to use on arm") set(ARM_FP_ABI ${ARM_FP_API} CACHE STRING "Floating point ABI to use on arm")
endif() endif()
mark_as_advanced(ARM_FP_ABI) mark_as_advanced(ARM_FP_ABI)
else()
if(NOT APPLE)
option(WITH_IPP "Use Intel Performance Primitives." OFF)
endif()
endif() endif()
option(WITH_JPEG "Use JPEG decoding." OFF) option(WITH_JPEG "Use JPEG decoding." OFF)
if(APPLE) if(APPLE)

View File

@ -144,8 +144,10 @@ set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS su
# NOTE: Currently both ARCHS_STANDARD_32_BIT and ARCHS_UNIVERSAL_IPHONE_OS set armv7 only, so set both manually # NOTE: Currently both ARCHS_STANDARD_32_BIT and ARCHS_UNIVERSAL_IPHONE_OS set armv7 only, so set both manually
if (${IOS_PLATFORM} STREQUAL "OS") if (${IOS_PLATFORM} STREQUAL "OS")
set (IOS_ARCH armv7 armv7s) set (IOS_ARCH armv7 armv7s)
set (CMAKE_SYSTEM_PROCESSOR armv7)
else (${IOS_PLATFORM} STREQUAL "OS") else (${IOS_PLATFORM} STREQUAL "OS")
set (IOS_ARCH i386) set (IOS_ARCH i386)
set (CMAKE_SYSTEM_PROCESSOR i386)
endif (${IOS_PLATFORM} STREQUAL "OS") endif (${IOS_PLATFORM} STREQUAL "OS")
set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS") set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS")

View File

@ -113,7 +113,6 @@ typedef struct _RFX_CONTEXT RFX_CONTEXT;
FREERDP_API RFX_CONTEXT* rfx_context_new(void); FREERDP_API RFX_CONTEXT* rfx_context_new(void);
FREERDP_API void rfx_context_free(RFX_CONTEXT* context); FREERDP_API void rfx_context_free(RFX_CONTEXT* context);
FREERDP_API void rfx_context_set_cpu_opt(RFX_CONTEXT* context, UINT32 cpu_opt);
FREERDP_API void rfx_context_set_pixel_format(RFX_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format); FREERDP_API void rfx_context_set_pixel_format(RFX_CONTEXT* context, RDP_PIXEL_FORMAT pixel_format);
FREERDP_API void rfx_context_reset(RFX_CONTEXT* context); FREERDP_API void rfx_context_reset(RFX_CONTEXT* context);

View File

@ -39,9 +39,9 @@ typedef struct rdp_input rdpInput;
#define PTR_FLAGS_WHEEL_NEGATIVE 0x0100 #define PTR_FLAGS_WHEEL_NEGATIVE 0x0100
#define PTR_FLAGS_MOVE 0x0800 #define PTR_FLAGS_MOVE 0x0800
#define PTR_FLAGS_DOWN 0x8000 #define PTR_FLAGS_DOWN 0x8000
#define PTR_FLAGS_BUTTON1 0x1000 #define PTR_FLAGS_BUTTON1 0x1000 //left
#define PTR_FLAGS_BUTTON2 0x2000 #define PTR_FLAGS_BUTTON2 0x2000 //right
#define PTR_FLAGS_BUTTON3 0x4000 #define PTR_FLAGS_BUTTON3 0x4000 //middle
#define WheelRotationMask 0x01FF #define WheelRotationMask 0x01FF
/* Extended Pointer Flags */ /* Extended Pointer Flags */

View File

@ -190,9 +190,6 @@ typedef struct
__yCbCrToRGB_16s16s_P3P3_t yCbCrToRGB_16s16s_P3P3; __yCbCrToRGB_16s16s_P3P3_t yCbCrToRGB_16s16s_P3P3;
__RGBToYCbCr_16s16s_P3P3_t RGBToYCbCr_16s16s_P3P3; __RGBToYCbCr_16s16s_P3P3_t RGBToYCbCr_16s16s_P3P3;
__RGBToRGB_16s8u_P3AC4R_t RGBToRGB_16s8u_P3AC4R; __RGBToRGB_16s8u_P3AC4R_t RGBToRGB_16s8u_P3AC4R;
/* internal use for CPU flags and such. */
void *hints;
} primitives_t; } primitives_t;
#ifdef __cplusplus #ifdef __cplusplus
@ -202,12 +199,6 @@ extern "C" {
/* Prototypes for the externally-visible entrypoints. */ /* Prototypes for the externally-visible entrypoints. */
FREERDP_API void primitives_init(void); FREERDP_API void primitives_init(void);
FREERDP_API primitives_t *primitives_get(void); FREERDP_API primitives_t *primitives_get(void);
FREERDP_API UINT32 primitives_get_flags(
const primitives_t *prims);
FREERDP_API void primitives_flags_str(
const primitives_t *prims,
char *str,
size_t len);
FREERDP_API void primitives_deinit(void); FREERDP_API void primitives_deinit(void);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -681,7 +681,8 @@ struct rdp_settings
ALIGN64 BOOL AsyncInput; /* 1544 */ ALIGN64 BOOL AsyncInput; /* 1544 */
ALIGN64 BOOL AsyncUpdate; /* 1545 */ ALIGN64 BOOL AsyncUpdate; /* 1545 */
ALIGN64 BOOL AsyncChannels; /* 1546 */ ALIGN64 BOOL AsyncChannels; /* 1546 */
UINT64 padding1600[1600 - 1547]; /* 1547 */ ALIGN64 BOOL ToggleFullscreen; /* 1547 */
UINT64 padding1600[1600 - 1548]; /* 1548 */
/* Miscellaneous */ /* Miscellaneous */
ALIGN64 BOOL SoftwareGdi; /* 1601 */ ALIGN64 BOOL SoftwareGdi; /* 1601 */

View File

@ -69,13 +69,6 @@ if(WITH_SSE2)
endif() endif()
if(WITH_NEON) if(WITH_NEON)
if(ANDROID)
set(ANDROID_CPU_FEATURES_PATH "${ANDROID_NDK}/sources/android/cpufeatures")
include_directories(${ANDROID_CPU_FEATURES_PATH})
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS}
${ANDROID_CPU_FEATURES_PATH}/cpu-features.c
${ANDROID_CPU_FEATURES_PATH}/cpu-features.h)
endif()
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_NEON_SRCS}) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_NEON_SRCS})
set_source_files_properties(${${MODULE_PREFIX}_NEON_SRCS} PROPERTIES COMPILE_FLAGS "-mfpu=neon -mfloat-abi=${ARM_FP_ABI} -Wno-unused-variable") set_source_files_properties(${${MODULE_PREFIX}_NEON_SRCS} PROPERTIES COMPILE_FLAGS "-mfpu=neon -mfloat-abi=${ARM_FP_ABI} -Wno-unused-variable")
endif() endif()

View File

@ -238,13 +238,6 @@ RFX_CONTEXT* rfx_context_new(void)
return context; return context;
} }
void rfx_context_set_cpu_opt(RFX_CONTEXT* context, UINT32 cpu_opt)
{
/* enable SIMD CPU acceleration if detected */
if (cpu_opt & CPU_SSE2)
RFX_INIT_SIMD(context);
}
void rfx_context_free(RFX_CONTEXT* context) void rfx_context_free(RFX_CONTEXT* context)
{ {
free(context->quants); free(context->quants);

View File

@ -27,14 +27,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <arm_neon.h> #include <arm_neon.h>
#include <winpr/sysinfo.h>
#include "rfx_types.h" #include "rfx_types.h"
#include "rfx_neon.h" #include "rfx_neon.h"
#if ANDROID
#include "cpu-features.h"
#endif
/* rfx_decode_YCbCr_to_RGB_NEON code now resides in the primitives library. */ /* rfx_decode_YCbCr_to_RGB_NEON code now resides in the primitives library. */
static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) static __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
@ -252,43 +249,9 @@ void rfx_dwt_2d_decode_NEON(INT16 * buffer, INT16 * dwt_buffer)
rfx_dwt_2d_decode_block_NEON(buffer, dwt_buffer, 32); rfx_dwt_2d_decode_block_NEON(buffer, dwt_buffer, 32);
} }
int isNeonSupported()
{
#if ANDROID
if (android_getCpuFamily() != ANDROID_CPU_FAMILY_ARM)
{
DEBUG_RFX("NEON optimization disabled - No ARM CPU found");
return 0;
}
UINT64 features = android_getCpuFeatures();
if ((features & ANDROID_CPU_ARM_FEATURE_ARMv7))
{
if (features & ANDROID_CPU_ARM_FEATURE_NEON)
{
DEBUG_RFX("NEON optimization enabled!");
return FALSE;
}
DEBUG_RFX("NEON optimization disabled - CPU not NEON capable");
}
else
{
DEBUG_RFX("NEON optimization disabled - No ARMv7 CPU found");
}
return FALSE;
#elif defined(__APPLE)
/* assume NEON support on iOS devices */
return TRUE;
#else
return FALSE;
#endif
}
void rfx_init_neon(RFX_CONTEXT * context) void rfx_init_neon(RFX_CONTEXT * context)
{ {
if (isNeonSupported()) if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE))
{ {
DEBUG_RFX("Using NEON optimizations"); DEBUG_RFX("Using NEON optimizations");

View File

@ -25,6 +25,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <winpr/sysinfo.h>
#include <xmmintrin.h> #include <xmmintrin.h>
#include <emmintrin.h> #include <emmintrin.h>
@ -490,6 +491,10 @@ static void rfx_dwt_2d_encode_sse2(INT16* buffer, INT16* dwt_buffer)
void rfx_init_sse2(RFX_CONTEXT* context) void rfx_init_sse2(RFX_CONTEXT* context)
{ {
if (!IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE))
return;
DEBUG_RFX("Using SSE2 optimizations"); DEBUG_RFX("Using SSE2 optimizations");
IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_sse2"); IF_PROFILER(context->priv->prof_rfx_quantization_decode->name = "rfx_quantization_decode_sse2");

View File

@ -63,15 +63,6 @@ elseif(WITH_NEON)
# TODO: Add MSVC equivalent # TODO: Add MSVC equivalent
endif() endif()
# required for android cpu detection
if(ANDROID)
set(ANDROID_CPU_FEATURES_PATH "${ANDROID_NDK}/sources/android/cpufeatures")
include_directories(${ANDROID_CPU_FEATURES_PATH})
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS}
${ANDROID_CPU_FEATURES_PATH}/cpu-features.c
${ANDROID_CPU_FEATURES_PATH}/cpu-features.h)
endif()
set_property(SOURCE ${${MODULE_PREFIX}_OPT_SRCS} PROPERTY COMPILE_FLAGS ${OPTIMIZATION}) set_property(SOURCE ${${MODULE_PREFIX}_OPT_SRCS} PROPERTY COMPILE_FLAGS ${OPTIMIZATION})
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_OPT_SRCS}) set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} ${${MODULE_PREFIX}_OPT_SRCS})
@ -91,6 +82,11 @@ if(IPP_FOUND)
endforeach() endforeach()
endif() endif()
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD}
MODULE winpr
MODULES winpr-sysinfo)
if(MONOLITHIC_BUILD) if(MONOLITHIC_BUILD)
set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE) set(FREERDP_LIBS ${FREERDP_LIBS} ${${MODULE_PREFIX}_LIBS} PARENT_SCOPE)
else() else()

View File

@ -62,10 +62,7 @@ New Optimizations
----------------- -----------------
As the need arises, new optimizations can be added to the library, As the need arises, new optimizations can be added to the library,
including NEON, AVX, and perhaps OpenCL or other SIMD implementations. including NEON, AVX, and perhaps OpenCL or other SIMD implementations.
The initialization routine is free to do any quick run-time test to The CPU feature detection is done in winpr/sysinfo.
determine which features are available before hooking the operation's
function pointer, or it can simply look at the processor features list
from the hints passed to the initialization routine.
Adding Entrypoints Adding Entrypoints
@ -85,15 +82,6 @@ be added.
The template functions can frequently be used to extend the The template functions can frequently be used to extend the
operations without writing a lot of new code. operations without writing a lot of new code.
Flags
-----
The entrypoint primitives_get_flags() returns a bitfield of processor flags
(as defined in primitives.h) and primitives_flag_str() returns a string
related to those processor flags, for debugging and information. The
bitfield can be used elsewhere in the code as needed.
Cache Management Cache Management
---------------- ----------------
I haven't found a lot of speed improvement by attempting prefetch, and I haven't found a lot of speed improvement by attempting prefetch, and

View File

@ -46,12 +46,11 @@ pstatus_t general_add_16s(
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_add( void primitives_init_add(
const primitives_hints_t *hints,
primitives_t *prims) primitives_t *prims)
{ {
prims->add_16s = general_add_16s; prims->add_16s = general_add_16s;
primitives_init_add_opt(hints, prims); primitives_init_add_opt(prims);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -24,7 +24,7 @@
pstatus_t general_add_16s(const INT16 *pSrc1, const INT16 *pSrc2, INT16 *pDst, INT32 len); pstatus_t general_add_16s(const INT16 *pSrc1, const INT16 *pSrc2, INT16 *pDst, INT32 len);
void primitives_init_add_opt(const primitives_hints_t *hints, primitives_t *prims); void primitives_init_add_opt(primitives_t *prims);
#endif /* !__PRIM_ADD_H_INCLUDED__ */ #endif /* !__PRIM_ADD_H_INCLUDED__ */

View File

@ -20,6 +20,7 @@
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <winpr/sysinfo.h>
#ifdef WITH_SSE2 #ifdef WITH_SSE2
#include <emmintrin.h> #include <emmintrin.h>
@ -45,18 +46,15 @@ SSE3_SSD_ROUTINE(sse3_add_16s, INT16, general_add_16s,
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_add_opt( void primitives_init_add_opt(
const primitives_hints_t *hints,
primitives_t *prims) primitives_t *prims)
{ {
#ifdef WITH_IPP #ifdef WITH_IPP
prims->add_16s = (__add_16s_t) ippsAdd_16s; prims->add_16s = (__add_16s_t) ippsAdd_16s;
#elif defined(WITH_SSE2) #elif defined(WITH_SSE2)
if ((hints->x86_flags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE)
&& (hints->x86_flags & PRIM_X86_SSE3_AVAILABLE)) /* for LDDQU */ && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) /* for LDDQU */
{ {
prims->add_16s = sse3_add_16s; prims->add_16s = sse3_add_16s;
} }
#endif #endif
} }

View File

@ -102,11 +102,11 @@ pstatus_t general_alphaComp_argb(
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_alphaComp(const primitives_hints_t* hints, primitives_t* prims) void primitives_init_alphaComp(primitives_t* prims)
{ {
prims->alphaComp_argb = general_alphaComp_argb; prims->alphaComp_argb = general_alphaComp_argb;
primitives_init_alphaComp_opt(hints, prims); primitives_init_alphaComp_opt(prims);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -24,7 +24,7 @@
pstatus_t general_alphaComp_argb(const BYTE *pSrc1, INT32 src1Step, const BYTE *pSrc2, INT32 src2Step, BYTE *pDst, INT32 dstStep, INT32 width, INT32 height); pstatus_t general_alphaComp_argb(const BYTE *pSrc1, INT32 src1Step, const BYTE *pSrc2, INT32 src2Step, BYTE *pDst, INT32 dstStep, INT32 width, INT32 height);
void primitives_init_alphaComp_opt(const primitives_hints_t* hints, primitives_t* prims); void primitives_init_alphaComp_opt(primitives_t* prims);
#endif /* !__PRIM_ALPHACOMP_H_INCLUDED__ */ #endif /* !__PRIM_ALPHACOMP_H_INCLUDED__ */

View File

@ -26,6 +26,7 @@
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <winpr/sysinfo.h>
#ifdef WITH_SSE2 #ifdef WITH_SSE2
#include <emmintrin.h> #include <emmintrin.h>
@ -210,13 +211,13 @@ pstatus_t ipp_alphaComp_argb(
#endif #endif
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_alphaComp_opt(const primitives_hints_t* hints, primitives_t* prims) void primitives_init_alphaComp_opt(primitives_t* prims)
{ {
#ifdef WITH_IPP #ifdef WITH_IPP
prims->alphaComp_argb = ipp_alphaComp_argb; prims->alphaComp_argb = ipp_alphaComp_argb;
#elif defined(WITH_SSE2) #elif defined(WITH_SSE2)
if ((hints->x86_flags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE)
&& (hints->x86_flags & PRIM_X86_SSE3_AVAILABLE)) /* for LDDQU */ && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) /* for LDDQU */
{ {
prims->alphaComp_argb = sse2_alphaComp_argb; prims->alphaComp_argb = sse2_alphaComp_argb;
} }

View File

@ -61,14 +61,13 @@ pstatus_t general_orC_32u(
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_andor( void primitives_init_andor(
const primitives_hints_t *hints,
primitives_t *prims) primitives_t *prims)
{ {
/* Start with the default. */ /* Start with the default. */
prims->andC_32u = general_andC_32u; prims->andC_32u = general_andC_32u;
prims->orC_32u = general_orC_32u; prims->orC_32u = general_orC_32u;
primitives_init_andor_opt(hints, prims); primitives_init_andor_opt(prims);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -25,7 +25,7 @@
pstatus_t general_andC_32u(const UINT32 *pSrc, UINT32 val, UINT32 *pDst, INT32 len); pstatus_t general_andC_32u(const UINT32 *pSrc, UINT32 val, UINT32 *pDst, INT32 len);
pstatus_t general_orC_32u(const UINT32 *pSrc, UINT32 val, UINT32 *pDst, INT32 len); pstatus_t general_orC_32u(const UINT32 *pSrc, UINT32 val, UINT32 *pDst, INT32 len);
void primitives_init_andor_opt(const primitives_hints_t *hints, primitives_t *prims); void primitives_init_andor_opt(primitives_t *prims);
#endif /* !__PRIM_ANDOR_H_INCLUDED__ */ #endif /* !__PRIM_ANDOR_H_INCLUDED__ */

View File

@ -19,6 +19,7 @@
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <winpr/sysinfo.h>
#ifdef WITH_SSE2 #ifdef WITH_SSE2
#include <emmintrin.h> #include <emmintrin.h>
@ -45,14 +46,14 @@ SSE3_SCD_PRE_ROUTINE(sse3_orC_32u, UINT32, general_orC_32u,
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_andor_opt(const primitives_hints_t *hints, primitives_t *prims) void primitives_init_andor_opt(primitives_t *prims)
{ {
#if defined(WITH_IPP) #if defined(WITH_IPP)
prims->andC_32u = (__andC_32u_t) ippsAndC_32u; prims->andC_32u = (__andC_32u_t) ippsAndC_32u;
prims->orC_32u = (__orC_32u_t) ippsOrC_32u; prims->orC_32u = (__orC_32u_t) ippsOrC_32u;
#elif defined(WITH_SSE2) #elif defined(WITH_SSE2)
if ((hints->x86_flags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE)
&& (hints->x86_flags & PRIM_X86_SSE3_AVAILABLE)) && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
{ {
prims->andC_32u = sse3_andC_32u; prims->andC_32u = sse3_andC_32u;
prims->orC_32u = sse3_orC_32u; prims->orC_32u = sse3_orC_32u;

View File

@ -215,13 +215,13 @@ pstatus_t general_RGBToRGB_16s8u_P3AC4R(
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_colors(const primitives_hints_t* hints, primitives_t* prims) void primitives_init_colors(primitives_t* prims)
{ {
prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R; prims->RGBToRGB_16s8u_P3AC4R = general_RGBToRGB_16s8u_P3AC4R;
prims->yCbCrToRGB_16s16s_P3P3 = general_yCbCrToRGB_16s16s_P3P3; prims->yCbCrToRGB_16s16s_P3P3 = general_yCbCrToRGB_16s16s_P3P3;
prims->RGBToYCbCr_16s16s_P3P3 = general_RGBToYCbCr_16s16s_P3P3; prims->RGBToYCbCr_16s16s_P3P3 = general_RGBToYCbCr_16s16s_P3P3;
primitives_init_colors_opt(hints, prims); primitives_init_colors_opt(prims);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -26,7 +26,7 @@ pstatus_t general_yCbCrToRGB_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, IN
pstatus_t general_RGBToYCbCr_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, const prim_size_t *roi); pstatus_t general_RGBToYCbCr_16s16s_P3P3(const INT16 *pSrc[3], INT32 srcStep, INT16 *pDst[3], INT32 dstStep, const prim_size_t *roi);
pstatus_t general_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3], int srcStep, BYTE *pDst, int dstStep, const prim_size_t *roi); pstatus_t general_RGBToRGB_16s8u_P3AC4R(const INT16 *pSrc[3], int srcStep, BYTE *pDst, int dstStep, const prim_size_t *roi);
void primitives_init_colors_opt(const primitives_hints_t* hints, primitives_t* prims); void primitives_init_colors_opt(primitives_t* prims);
#endif /* !__PRIM_COLORS_H_INCLUDED__ */ #endif /* !__PRIM_COLORS_H_INCLUDED__ */

View File

@ -23,6 +23,7 @@
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <winpr/sysinfo.h>
#ifdef WITH_SSE2 #ifdef WITH_SSE2
#include <emmintrin.h> #include <emmintrin.h>
@ -542,17 +543,17 @@ pstatus_t neon_yCbCrToRGB_16s16s_P3P3(
*/ */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_colors_opt(const primitives_hints_t* hints, primitives_t* prims) void primitives_init_colors_opt(primitives_t* prims)
{ {
#if defined(WITH_SSE2) #if defined(WITH_SSE2)
if (hints->x86_flags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
prims->RGBToRGB_16s8u_P3AC4R = sse2_RGBToRGB_16s8u_P3AC4R; prims->RGBToRGB_16s8u_P3AC4R = sse2_RGBToRGB_16s8u_P3AC4R;
prims->yCbCrToRGB_16s16s_P3P3 = sse2_yCbCrToRGB_16s16s_P3P3; prims->yCbCrToRGB_16s16s_P3P3 = sse2_yCbCrToRGB_16s16s_P3P3;
prims->RGBToYCbCr_16s16s_P3P3 = sse2_RGBToYCbCr_16s16s_P3P3; prims->RGBToYCbCr_16s16s_P3P3 = sse2_RGBToYCbCr_16s16s_P3P3;
} }
#elif defined(WITH_NEON) #elif defined(WITH_NEON)
if (hints->arm_flags & PRIM_ARM_NEON_AVAILABLE) if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE))
{ {
prims->yCbCrToRGB_16s16s_P3P3 = neon_yCbCrToRGB_16s16s_P3P3; prims->yCbCrToRGB_16s16s_P3P3 = neon_yCbCrToRGB_16s16s_P3P3;
} }

View File

@ -148,7 +148,6 @@ static pstatus_t ippiCopy_8u_AC4r(
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_copy( void primitives_init_copy(
const primitives_hints_t *hints,
primitives_t *prims) primitives_t *prims)
{ {
/* Start with the default. */ /* Start with the default. */

View File

@ -34,61 +34,43 @@
? _mm_lddqu_si128((__m128i *) (_ptr_)) \ ? _mm_lddqu_si128((__m128i *) (_ptr_)) \
: _mm_load_si128((__m128i *) (_ptr_))) : _mm_load_si128((__m128i *) (_ptr_)))
/* This structure can (eventually) be used to provide hints to the
* initialization routines, e.g. whether SSE2 or NEON or IPP instructions
* or calls are available.
*/
typedef struct
{
UINT32 x86_flags;
UINT32 arm_flags;
} primitives_hints_t;
/* Function prototypes for all the init/deinit routines. */ /* Function prototypes for all the init/deinit routines. */
extern void primitives_init_copy( extern void primitives_init_copy(
const primitives_hints_t *hints,
primitives_t *prims); primitives_t *prims);
extern void primitives_deinit_copy( extern void primitives_deinit_copy(
primitives_t *prims); primitives_t *prims);
extern void primitives_init_set( extern void primitives_init_set(
const primitives_hints_t *hints,
primitives_t *prims); primitives_t *prims);
extern void primitives_deinit_set( extern void primitives_deinit_set(
primitives_t *prims); primitives_t *prims);
extern void primitives_init_add( extern void primitives_init_add(
const primitives_hints_t *hints,
primitives_t *prims); primitives_t *prims);
extern void primitives_deinit_add( extern void primitives_deinit_add(
primitives_t *prims); primitives_t *prims);
extern void primitives_init_andor( extern void primitives_init_andor(
const primitives_hints_t *hints,
primitives_t *prims); primitives_t *prims);
extern void primitives_deinit_andor( extern void primitives_deinit_andor(
primitives_t *prims); primitives_t *prims);
extern void primitives_init_shift( extern void primitives_init_shift(
const primitives_hints_t *hints,
primitives_t *prims); primitives_t *prims);
extern void primitives_deinit_shift( extern void primitives_deinit_shift(
primitives_t *prims); primitives_t *prims);
extern void primitives_init_sign( extern void primitives_init_sign(
const primitives_hints_t *hints,
primitives_t *prims); primitives_t *prims);
extern void primitives_deinit_sign( extern void primitives_deinit_sign(
primitives_t *prims); primitives_t *prims);
extern void primitives_init_alphaComp( extern void primitives_init_alphaComp(
const primitives_hints_t *hints,
primitives_t *prims); primitives_t *prims);
extern void primitives_deinit_alphaComp( extern void primitives_deinit_alphaComp(
primitives_t *prims); primitives_t *prims);
extern void primitives_init_colors( extern void primitives_init_colors(
const primitives_hints_t *hints,
primitives_t *prims); primitives_t *prims);
extern void primitives_deinit_colors( extern void primitives_deinit_colors(
primitives_t *prims); primitives_t *prims);

View File

@ -111,7 +111,6 @@ pstatus_t general_set_32u(
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_set( void primitives_init_set(
const primitives_hints_t *hints,
primitives_t *prims) primitives_t *prims)
{ {
/* Start with the default. */ /* Start with the default. */
@ -120,7 +119,7 @@ void primitives_init_set(
prims->set_32u = general_set_32u; prims->set_32u = general_set_32u;
prims->zero = general_zero; prims->zero = general_zero;
primitives_init_set_opt(hints, prims); primitives_init_set_opt(prims);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -28,7 +28,7 @@ pstatus_t general_set_32s(INT32 val, INT32 *pDst, INT32 len);
pstatus_t general_set_32u(UINT32 val, UINT32 *pDst, INT32 len); pstatus_t general_set_32u(UINT32 val, UINT32 *pDst, INT32 len);
void primitives_init_set_opt(const primitives_hints_t *hints, primitives_t *prims); void primitives_init_set_opt(primitives_t *prims);
#endif /* !__PRIM_SET_H_INCLUDED__ */ #endif /* !__PRIM_SET_H_INCLUDED__ */

View File

@ -21,6 +21,7 @@
#include <string.h> #include <string.h>
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <winpr/sysinfo.h>
#ifdef WITH_SSE2 #ifdef WITH_SSE2
# include <emmintrin.h> # include <emmintrin.h>
@ -198,7 +199,7 @@ pstatus_t ipp_wrapper_set_32u(
#endif #endif
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_set_opt(const primitives_hints_t *hints, primitives_t *prims) void primitives_init_set_opt(primitives_t *prims)
{ {
/* Pick tuned versions if possible. */ /* Pick tuned versions if possible. */
#ifdef WITH_IPP #ifdef WITH_IPP
@ -207,7 +208,7 @@ void primitives_init_set_opt(const primitives_hints_t *hints, primitives_t *prim
prims->set_32u = (__set_32u_t) ipp_wrapper_set_32u; prims->set_32u = (__set_32u_t) ipp_wrapper_set_32u;
prims->zero = (__zero_t) ippsZero_8u; prims->zero = (__zero_t) ippsZero_8u;
#elif defined(WITH_SSE2) #elif defined(WITH_SSE2)
if (hints->x86_flags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
prims->set_8u = sse2_set_8u; prims->set_8u = sse2_set_8u;
prims->set_32s = sse2_set_32s; prims->set_32s = sse2_set_32s;

View File

@ -104,7 +104,6 @@ pstatus_t general_shiftC_16u(
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_shift( void primitives_init_shift(
const primitives_hints_t *hints,
primitives_t *prims) primitives_t *prims)
{ {
/* Start with the default. */ /* Start with the default. */
@ -117,7 +116,7 @@ void primitives_init_shift(
prims->shiftC_16s = general_shiftC_16s; prims->shiftC_16s = general_shiftC_16s;
prims->shiftC_16u = general_shiftC_16u; prims->shiftC_16u = general_shiftC_16u;
primitives_init_shift_opt(hints, prims); primitives_init_shift_opt(prims);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -29,7 +29,7 @@ pstatus_t general_rShiftC_16u(const UINT16 *pSrc, INT32 val, UINT16 *pDst, INT32
pstatus_t general_shiftC_16s(const INT16 *pSrc, INT32 val, INT16 *pDst, INT32 len); pstatus_t general_shiftC_16s(const INT16 *pSrc, INT32 val, INT16 *pDst, INT32 len);
pstatus_t general_shiftC_16u(const UINT16 *pSrc, INT32 val, UINT16 *pDst, INT32 len); pstatus_t general_shiftC_16u(const UINT16 *pSrc, INT32 val, UINT16 *pDst, INT32 len);
void primitives_init_shift_opt(const primitives_hints_t *hints, primitives_t *prims); void primitives_init_shift_opt(primitives_t *prims);
#endif /* !__PRIM_SHIFT_H_INCLUDED__ */ #endif /* !__PRIM_SHIFT_H_INCLUDED__ */

View File

@ -19,6 +19,7 @@
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <winpr/sysinfo.h>
#ifdef WITH_SSE2 #ifdef WITH_SSE2
#include <emmintrin.h> #include <emmintrin.h>
@ -58,7 +59,7 @@ SSE3_SCD_ROUTINE(sse2_rShiftC_16u, UINT16, general_rShiftC_16u,
*/ */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_shift_opt(const primitives_hints_t *hints, primitives_t *prims) void primitives_init_shift_opt(primitives_t *prims)
{ {
#if defined(WITH_IPP) #if defined(WITH_IPP)
prims->lShiftC_16s = (__lShiftC_16s_t) ippsLShiftC_16s; prims->lShiftC_16s = (__lShiftC_16s_t) ippsLShiftC_16s;
@ -66,8 +67,8 @@ void primitives_init_shift_opt(const primitives_hints_t *hints, primitives_t *pr
prims->lShiftC_16u = (__lShiftC_16u_t) ippsLShiftC_16u; prims->lShiftC_16u = (__lShiftC_16u_t) ippsLShiftC_16u;
prims->rShiftC_16u = (__rShiftC_16u_t) ippsRShiftC_16u; prims->rShiftC_16u = (__rShiftC_16u_t) ippsRShiftC_16u;
#elif defined(WITH_SSE2) #elif defined(WITH_SSE2)
if ((hints->x86_flags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE)
&& (hints->x86_flags & PRIM_X86_SSE3_AVAILABLE)) && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
{ {
prims->lShiftC_16s = sse2_lShiftC_16s; prims->lShiftC_16s = sse2_lShiftC_16s;
prims->rShiftC_16s = sse2_rShiftC_16s; prims->rShiftC_16s = sse2_rShiftC_16s;

View File

@ -42,13 +42,12 @@ pstatus_t general_sign_16s(
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_sign( void primitives_init_sign(
const primitives_hints_t *hints,
primitives_t *prims) primitives_t *prims)
{ {
/* Start with the default. */ /* Start with the default. */
prims->sign_16s = general_sign_16s; prims->sign_16s = general_sign_16s;
primitives_init_sign_opt(hints, prims); primitives_init_sign_opt(prims);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -24,7 +24,7 @@
pstatus_t general_sign_16s(const INT16 *pSrc, INT16 *pDst, INT32 len); pstatus_t general_sign_16s(const INT16 *pSrc, INT16 *pDst, INT32 len);
void primitives_init_sign_opt(const primitives_hints_t *hints, primitives_t *prims); void primitives_init_sign_opt(primitives_t *prims);
#endif /* !__PRIM_SIGN_H_INCLUDED__ */ #endif /* !__PRIM_SIGN_H_INCLUDED__ */

View File

@ -19,6 +19,7 @@
#include <freerdp/types.h> #include <freerdp/types.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <winpr/sysinfo.h>
#ifdef WITH_SSE2 #ifdef WITH_SSE2
#include <emmintrin.h> #include <emmintrin.h>
@ -134,13 +135,13 @@ pstatus_t ssse3_sign_16s(
#endif /* WITH_SSE2 */ #endif /* WITH_SSE2 */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init_sign_opt(const primitives_hints_t *hints, primitives_t *prims) void primitives_init_sign_opt(primitives_t *prims)
{ {
/* Pick tuned versions if possible. */ /* Pick tuned versions if possible. */
/* I didn't spot an IPP version of this. */ /* I didn't spot an IPP version of this. */
#if defined(WITH_SSE2) #if defined(WITH_SSE2)
if ((hints->x86_flags & PRIM_X86_SSSE3_AVAILABLE) if (IsProcessorFeaturePresentEx(PF_EX_SSSE3)
&& (hints->x86_flags & PRIM_X86_SSE3_AVAILABLE)) && IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
{ {
prims->sign_16s = ssse3_sign_16s; prims->sign_16s = ssse3_sign_16s;
} }

View File

@ -22,173 +22,16 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <winpr/platform.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include "prim_internal.h" #include "prim_internal.h"
#ifdef __ANDROID__
#include "cpu-features.h"
#endif
/* Singleton pointer used throughout the program when requested. */ /* Singleton pointer used throughout the program when requested. */
static primitives_t* pPrimitives = NULL; static primitives_t* pPrimitives = NULL;
#define D_BIT_MMX (1<<23)
#define D_BIT_SSE (1<<25)
#define D_BIT_SSE2 (1<<26)
#define D_BIT_3DN (1<<30)
#define C_BIT_SSE3 (1<<0)
#define C_BIT_3DNP (1<<8)
#define C_BIT_SSSE3 (1<<9)
#define C_BIT_SSE41 (1<<19)
#define C_BIT_SSE42 (1<<20)
#define C_BIT_XGETBV (1<<27)
#define C_BIT_AVX (1<<28)
#define C_BITS_AVX (C_BIT_XGETBV|C_BIT_AVX)
#define E_BIT_XMM (1<<1)
#define E_BIT_YMM (1<<2)
#define E_BITS_AVX (E_BIT_XMM|E_BIT_YMM)
#define C_BIT_FMA (1<<11)
#define C_BIT_AVX_AES (1<<24)
/* If x86 */
#if defined(_M_IX86_AMD64)
/* If GCC */
#ifdef __GNUC__
#ifdef __AVX__
#define xgetbv(_func_, _lo_, _hi_) \
__asm__ __volatile__ ("xgetbv" : "=a" (_lo_), "=d" (_hi_) : "c" (_func_))
#endif
static void cpuid(
unsigned info,
unsigned *eax,
unsigned *ebx,
unsigned *ecx,
unsigned *edx)
{
*eax = *ebx = *ecx = *edx = 0;
__asm volatile
(
/* The EBX (or RBX register on x86_64) is used for the PIC base address
* and must not be corrupted by our inline assembly.
*/
#ifdef _M_IX86
"mov %%ebx, %%esi;"
"cpuid;"
"xchg %%ebx, %%esi;"
#else
"mov %%rbx, %%rsi;"
"cpuid;"
"xchg %%rbx, %%rsi;"
#endif
: "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (info)
);
}
static void set_hints(primitives_hints_t* hints)
{
unsigned a, b, c, d;
cpuid(1, &a, &b, &c, &d);
if (d & D_BIT_MMX)
hints->x86_flags |= PRIM_X86_MMX_AVAILABLE;
if (d & D_BIT_SSE)
hints->x86_flags |= PRIM_X86_SSE_AVAILABLE;
if (d & D_BIT_SSE2)
hints->x86_flags |= PRIM_X86_SSE2_AVAILABLE;
if (d & D_BIT_3DN)
hints->x86_flags |= PRIM_X86_3DNOW_AVAILABLE;
if (c & C_BIT_3DNP)
hints->x86_flags |= PRIM_X86_3DNOW_PREFETCH_AVAILABLE;
if (c & C_BIT_SSE3)
hints->x86_flags |= PRIM_X86_SSE3_AVAILABLE;
if (c & C_BIT_SSSE3)
hints->x86_flags |= PRIM_X86_SSSE3_AVAILABLE;
if (c & C_BIT_SSE41)
hints->x86_flags |= PRIM_X86_SSE41_AVAILABLE;
if (c & C_BIT_SSE42)
hints->x86_flags |= PRIM_X86_SSE42_AVAILABLE;
#ifdef __AVX__
if ((c & C_BITS_AVX) == C_BITS_AVX)
{
int e, f;
xgetbv(0, e, f);
if ((e & E_BITS_AVX) == E_BITS_AVX)
{
hints->x86_flags |= PRIM_X86_AVX_AVAILABLE;
if (c & C_BIT_FMA)
hints->x86_flags |= PRIM_X86_FMA_AVAILABLE;
if (c & C_BIT_AVX_AES)
hints->x86_flags |= PRIM_X86_AVX_AES_AVAILABLE;
}
}
/* TODO: AVX2: set eax=7, ecx=0, cpuid, check ebx-bit5 */
#endif
}
#else
static void set_hints(primitives_hints_t* hints)
{
/* x86 non-GCC: TODO */
}
#endif /* __GNUC__ */
/* ------------------------------------------------------------------------- */
#elif defined(_M_ARM)
static UINT32 getNeonSupport(void)
{
#ifdef __ANDROID__
if (android_getCpuFamily() != ANDROID_CPU_FAMILY_ARM) return 0;
UINT64 features = android_getCpuFeatures();
if ((features & ANDROID_CPU_ARM_FEATURE_ARMv7))
{
if (features & ANDROID_CPU_ARM_FEATURE_NEON)
{
return PRIM_ARM_NEON_AVAILABLE;
}
}
#elif defined(__APPLE)
/* assume NEON support on iOS devices */
return PRIM_ARM_NEON_AVAILABLE;
#endif
return 0;
}
static void set_hints(primitives_hints_t* hints)
{
/* ARM: TODO */
hints->arm_flags |= getNeonSupport();
}
#else
static void set_hints(
primitives_hints_t *hints)
{
}
#endif /* x86 else ARM else */
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_init(void) void primitives_init(void)
{ {
primitives_hints_t* hints;
if (pPrimitives == NULL) if (pPrimitives == NULL)
{ {
pPrimitives = calloc(1, sizeof(primitives_t)); pPrimitives = calloc(1, sizeof(primitives_t));
@ -197,19 +40,15 @@ void primitives_init(void)
return; return;
} }
hints = calloc(1, sizeof(primitives_hints_t));
set_hints(hints);
pPrimitives->hints = (void *) hints;
/* Now call each section's initialization routine. */ /* Now call each section's initialization routine. */
primitives_init_add(hints, pPrimitives); primitives_init_add(pPrimitives);
primitives_init_andor(hints, pPrimitives); primitives_init_andor(pPrimitives);
primitives_init_alphaComp(hints, pPrimitives); primitives_init_alphaComp(pPrimitives);
primitives_init_copy(hints, pPrimitives); primitives_init_copy(pPrimitives);
primitives_init_set(hints, pPrimitives); primitives_init_set(pPrimitives);
primitives_init_shift(hints, pPrimitives); primitives_init_shift(pPrimitives);
primitives_init_sign(hints, pPrimitives); primitives_init_sign(pPrimitives);
primitives_init_colors(hints, pPrimitives); primitives_init_colors(pPrimitives);
} }
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
@ -221,102 +60,6 @@ primitives_t* primitives_get(void)
return pPrimitives; return pPrimitives;
} }
/* ------------------------------------------------------------------------- */
UINT32 primitives_get_flags(const primitives_t* prims)
{
primitives_hints_t* hints = (primitives_hints_t*) (prims->hints);
#if defined(_M_IX86_AMD64)
return hints->x86_flags;
#elif defined(_M_ARM)
return hints->arm_flags;
#else
return 0;
#endif
}
/* ------------------------------------------------------------------------- */
typedef struct
{
UINT32 flag;
const char *str;
} flagpair_t;
static const flagpair_t x86_flags[] =
{
{ PRIM_X86_MMX_AVAILABLE, "MMX" },
{ PRIM_X86_3DNOW_AVAILABLE, "3DNow" },
{ PRIM_X86_3DNOW_PREFETCH_AVAILABLE, "3DNow-PF" },
{ PRIM_X86_SSE_AVAILABLE, "SSE" },
{ PRIM_X86_SSE2_AVAILABLE, "SSE2" },
{ PRIM_X86_SSE3_AVAILABLE, "SSE3" },
{ PRIM_X86_SSSE3_AVAILABLE, "SSSE3" },
{ PRIM_X86_SSE41_AVAILABLE, "SSE4.1" },
{ PRIM_X86_SSE42_AVAILABLE, "SSE4.2" },
{ PRIM_X86_AVX_AVAILABLE, "AVX" },
{ PRIM_X86_FMA_AVAILABLE, "FMA" },
{ PRIM_X86_AVX_AES_AVAILABLE, "AVX-AES" },
{ PRIM_X86_AVX2_AVAILABLE, "AVX2" },
};
static const flagpair_t arm_flags[] =
{
{ PRIM_ARM_VFP1_AVAILABLE, "VFP1" },
{ PRIM_ARM_VFP2_AVAILABLE, "VFP2" },
{ PRIM_ARM_VFP3_AVAILABLE, "VFP3" },
{ PRIM_ARM_VFP4_AVAILABLE, "VFP4" },
{ PRIM_ARM_FPA_AVAILABLE, "FPA" },
{ PRIM_ARM_FPE_AVAILABLE, "FPE" },
{ PRIM_ARM_IWMMXT_AVAILABLE, "IWMMXT" },
{ PRIM_ARM_NEON_AVAILABLE, "NEON" },
};
void primitives_flags_str(const primitives_t* prims, char* str, size_t len)
{
int i;
primitives_hints_t* hints;
*str = '\0';
--len; /* for the '/0' */
hints = (primitives_hints_t*) (prims->hints);
for (i = 0; i < sizeof(x86_flags) / sizeof(flagpair_t); ++i)
{
if (hints->x86_flags & x86_flags[i].flag)
{
int slen = strlen(x86_flags[i].str) + 1;
if (len < slen)
break;
if (*str != '\0')
strcat(str, " ");
strcat(str, x86_flags[i].str);
len -= slen;
}
}
for (i = 0; i < sizeof(arm_flags) / sizeof(flagpair_t); ++i)
{
if (hints->arm_flags & arm_flags[i].flag)
{
int slen = strlen(arm_flags[i].str) + 1;
if (len < slen)
break;
if (*str != '\0')
strcat(str, " ");
strcat(str, arm_flags[i].str);
len -= slen;
}
}
}
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
void primitives_deinit(void) void primitives_deinit(void)
{ {
@ -333,9 +76,6 @@ void primitives_deinit(void)
primitives_deinit_sign(pPrimitives); primitives_deinit_sign(pPrimitives);
primitives_deinit_colors(pPrimitives); primitives_deinit_colors(pPrimitives);
if (pPrimitives->hints != NULL)
free((void*) (pPrimitives->hints));
free((void*) pPrimitives); free((void*) pPrimitives);
pPrimitives = NULL; pPrimitives = NULL;
} }

View File

@ -138,7 +138,7 @@ endif()
set_property(SOURCE ${PRIMITIVE_TEST_CFILES} PROPERTY COMPILE_FLAGS ${OPTFLAGS}) set_property(SOURCE ${PRIMITIVE_TEST_CFILES} PROPERTY COMPILE_FLAGS ${OPTFLAGS})
target_link_libraries(prim_test rt) target_link_libraries(prim_test rt winpr-sysinfo)
if(NOT TESTING_OUTPUT_DIRECTORY) if(NOT TESTING_OUTPUT_DIRECTORY)
set(TESTING_OUTPUT_DIRECTORY .) set(TESTING_OUTPUT_DIRECTORY .)
endif() endif()

View File

@ -21,6 +21,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <winpr/platform.h>
#include <winpr/sysinfo.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#include <unistd.h> #include <unistd.h>
@ -32,6 +34,88 @@
int test_sizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 }; int test_sizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096 };
int Quiet = 0; int Quiet = 0;
/* ------------------------------------------------------------------------- */
typedef struct
{
UINT32 flag;
const char *str;
} flagpair_t;
static const flagpair_t flags[] =
{
#ifdef _M_IX86_AMD64
{ PF_MMX_INSTRUCTIONS_AVAILABLE, "MMX" },
{ PF_3DNOW_INSTRUCTIONS_AVAILABLE, "3DNow" },
{ PF_SSE_INSTRUCTIONS_AVAILABLE, "SSE" },
{ PF_SSE2_INSTRUCTIONS_AVAILABLE, "SSE2" },
{ PF_SSE3_INSTRUCTIONS_AVAILABLE, "SSE3" },
#elif defined(_M_ARM)
{ PF_ARM_VFP3, "VFP3" },
{ PF_ARM_INTEL_WMMX, "IWMMXT" },
{ PF_ARM_NEON_INSTRUCTIONS_AVAILABLE, "NEON" },
#endif
};
static const flagpair_t flags_extended[] =
{
#ifdef _M_IX86_AMD64
{ PF_EX_3DNOW_PREFETCH, "3DNow-PF" },
{ PF_EX_SSSE3, "SSSE3" },
{ PF_EX_SSE41, "SSE4.1" },
{ PF_EX_SSE42, "SSE4.2" },
{ PF_EX_AVX, "AVX" },
{ PF_EX_FMA, "FMA" },
{ PF_EX_AVX_AES, "AVX-AES" },
{ PF_EX_AVX2, "AVX2" },
#elif defined(_M_ARM)
{ PF_EX_ARM_VFP1, "VFP1"},
{ PF_EX_ARM_VFP4, "VFP4" },
#endif
};
void primitives_flags_str(char* str, size_t len)
{
int i;
*str = '\0';
--len; /* for the '/0' */
for (i = 0; i < sizeof(flags) / sizeof(flagpair_t); ++i)
{
if (IsProcessorFeaturePresent(flags[i].flag))
{
int slen = strlen(flags[i].str) + 1;
if (len < slen)
break;
if (*str != '\0')
strcat(str, " ");
strcat(str, flags[i].str);
len -= slen;
}
}
for (i = 0; i < sizeof(flags_extended) / sizeof(flagpair_t); ++i)
{
if (IsProcessorFeaturePresentEx(flags_extended[i].flag))
{
int slen = strlen(flags_extended[i].str) + 1;
if (len < slen)
break;
if (*str != '\0')
strcat(str, " ");
strcat(str, flags_extended[i].str);
len -= slen;
}
}
}
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static void get_random_data_lrand( static void get_random_data_lrand(
void *buffer, void *buffer,
@ -198,7 +282,7 @@ static const test_t testTypeList[] =
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
int i; int i;
char hints[256]; char hints[1024];
UINT32 testSet = 0; UINT32 testSet = 0;
UINT32 testTypes = 0; UINT32 testTypes = 0;
int results = SUCCESS; int results = SUCCESS;
@ -253,7 +337,7 @@ int main(int argc, char** argv)
primitives_init(); primitives_init();
primitives_flags_str(primitives_get(), hints, sizeof(hints)); primitives_flags_str(hints, sizeof(hints));
printf("Hints: %s\n", hints); printf("Hints: %s\n", hints);
/* COPY */ /* COPY */

View File

@ -29,6 +29,7 @@
#include <stdio.h> #include <stdio.h>
#include <freerdp/primitives.h> #include <freerdp/primitives.h>
#include <winpr/platform.h>
#ifdef WITH_IPP #ifdef WITH_IPP
#include <ipps.h> #include <ipps.h>
@ -100,7 +101,7 @@ extern int test_or_32u_speed(void);
/* Since so much of this code is repeated, define a macro to build /* Since so much of this code is repeated, define a macro to build
* functions to do speed tests. * functions to do speed tests.
*/ */
#ifdef armel #ifdef _M_ARM
#define SIMD_TYPE "Neon" #define SIMD_TYPE "Neon"
#else #else
#define SIMD_TYPE "SSE" #define SIMD_TYPE "SSE"
@ -121,8 +122,8 @@ extern int test_or_32u_speed(void);
} \ } \
} while (0) } while (0)
#if defined(i386) && defined(WITH_SSE2) #if (defined(_M_IX86_AMD64) && defined(WITH_SSE2)) || (defined(_M_ARM) && defined(WITH_NEON))
#define DO_SSE_MEASUREMENTS(_funcSSE_, _prework_) \ #define DO_OPT_MEASUREMENTS(_funcOpt_, _prework_) \
do { \ do { \
for (s=0; s<num_sizes; ++s) \ for (s=0; s<num_sizes; ++s) \
{ \ { \
@ -132,34 +133,15 @@ extern int test_or_32u_speed(void);
_prework_; \ _prework_; \
iter = iterations/size; \ iter = iterations/size; \
sprintf(label, "%s-%s-%-4d", SIMD_TYPE, oplabel, size); \ sprintf(label, "%s-%s-%-4d", SIMD_TYPE, oplabel, size); \
MEASURE_TIMED(label, iter, test_time, resultSSENeon[s], \ MEASURE_TIMED(label, iter, test_time, resultOpt[s], \
_funcSSE_); \ _funcOpt_); \
} \ } \
} while (0) } while (0)
#else #else
#define DO_SSE_MEASUREMENTS(_funcSSE_, _prework_) #define DO_OPT_MEASUREMENTS(_funcSSE_, _prework_)
#endif #endif
#if defined(armel) && defined(INCLUDE_NEON_MEASUREMENTS) #if defined(_M_IX86_AMD64) && defined(WITH_IPP)
#define DO_NEON_MEASUREMENTS(_funcNeon_, _prework_) \
do { \
for (s=0; s<num_sizes; ++s) \
{ \
int iter; \
char label[256]; \
int size = size_array[s]; \
_prework_; \
iter = iterations/size; \
sprintf(label, "%s-%s-%-4d", SIMD_TYPE, oplabel, size); \
MEASURE_TIMED(label, iter, test_time, resultSSENeon[s], \
_funcNeon_); \
} \
} while (0)
#else
#define DO_NEON_MEASUREMENTS(_funcNeon_, _prework_)
#endif
#if defined(i386) && defined(WITH_IPP)
#define DO_IPP_MEASUREMENTS(_funcIPP_, _prework_) \ #define DO_IPP_MEASUREMENTS(_funcIPP_, _prework_) \
do { \ do { \
for (s=0; s<num_sizes; ++s) \ for (s=0; s<num_sizes; ++s) \
@ -178,12 +160,12 @@ extern int test_or_32u_speed(void);
#define DO_IPP_MEASUREMENTS(_funcIPP_, _prework_) #define DO_IPP_MEASUREMENTS(_funcIPP_, _prework_)
#endif #endif
#define PRIM_NOP do {} while (0)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
#define STD_SPEED_TEST( \ #define STD_SPEED_TEST( \
_name_, _srctype_, _dsttype_, _prework_, \ _name_, _srctype_, _dsttype_, _prework_, \
_doNormal_, _funcNormal_, \ _doNormal_, _funcNormal_, \
_doSSE_, _funcSSE_, _flagsSSE_, \ _doOpt_, _funcOpt_, _flagOpt_, _flagExt_, \
_doNeon_, _funcNeon_, _flagsNeon_, \
_doIPP_, _funcIPP_) \ _doIPP_, _funcIPP_) \
static void _name_( \ static void _name_( \
const char *oplabel, const char *type, \ const char *oplabel, const char *type, \
@ -193,24 +175,28 @@ static void _name_( \
int iterations, float test_time) \ int iterations, float test_time) \
{ \ { \
int s; \ int s; \
float *resultNormal, *resultSSENeon, *resultIPP; \ float *resultNormal, *resultOpt, *resultIPP; \
UINT32 pflags = primitives_get_flags(primitives_get()); \
resultNormal = (float *) calloc(num_sizes, sizeof(float)); \ resultNormal = (float *) calloc(num_sizes, sizeof(float)); \
resultSSENeon = (float *) calloc(num_sizes, sizeof(float)); \ resultOpt = (float *) calloc(num_sizes, sizeof(float)); \
resultIPP = (float *) calloc(num_sizes, sizeof(float)); \ resultIPP = (float *) calloc(num_sizes, sizeof(float)); \
printf("******************** %s %s ******************\n", \ printf("******************** %s %s ******************\n", \
oplabel, type); \ oplabel, type); \
if (_doNormal_) { DO_NORMAL_MEASUREMENTS(_funcNormal_, _prework_); } \ if (_doNormal_) { DO_NORMAL_MEASUREMENTS(_funcNormal_, _prework_); } \
if (_doSSE_) { \ if (_doOpt_) \
if ((pflags & (_flagsSSE_)) == (_flagsSSE_)) \ { \
if (_flagExt_) \
{ \ { \
DO_SSE_MEASUREMENTS(_funcSSE_, _prework_); \ if (IsProcessorFeaturePresentEx(_flagOpt_)) \
{ \
DO_OPT_MEASUREMENTS(_funcOpt_, _prework_); \
} \
} \ } \
} \ else \
if (_doNeon_) { \
if ((pflags & (_flagsNeon_)) == (_flagsNeon_)) \
{ \ { \
DO_NEON_MEASUREMENTS(_funcNeon_, _prework_); \ if (IsProcessorFeaturePresent(_flagOpt_)) \
{ \
DO_OPT_MEASUREMENTS(_funcOpt_, _prework_); \
} \
} \ } \
} \ } \
if (_doIPP_) { DO_IPP_MEASUREMENTS(_funcIPP_, _prework_); } \ if (_doIPP_) { DO_IPP_MEASUREMENTS(_funcIPP_, _prework_); } \
@ -223,13 +209,13 @@ static void _name_( \
strcpy(sN, "N/A"); strcpy(sSN, "N/A"); strcpy(sSNp, "N/A"); \ strcpy(sN, "N/A"); strcpy(sSN, "N/A"); strcpy(sSNp, "N/A"); \
strcpy(sIPP, "N/A"); strcpy(sIPPp, "N/A"); \ strcpy(sIPP, "N/A"); strcpy(sIPPp, "N/A"); \
if (resultNormal[s] > 0.0) _floatprint(resultNormal[s], sN); \ if (resultNormal[s] > 0.0) _floatprint(resultNormal[s], sN); \
if (resultSSENeon[s] > 0.0) \ if (resultOpt[s] > 0.0) \
{ \ { \
_floatprint(resultSSENeon[s], sSN); \ _floatprint(resultOpt[s], sSN); \
if (resultNormal[s] > 0.0) \ if (resultNormal[s] > 0.0) \
{ \ { \
sprintf(sSNp, "%d%%", \ sprintf(sSNp, "%d%%", \
(int) (resultSSENeon[s] / resultNormal[s] * 100.0 + 0.5)); \ (int) (resultOpt[s] / resultNormal[s] * 100.0 + 0.5)); \
} \ } \
} \ } \
if (resultIPP[s] > 0.0) \ if (resultIPP[s] > 0.0) \
@ -244,7 +230,7 @@ static void _name_( \
printf("%8d: %15s %15s %5s %15s %5s\n", \ printf("%8d: %15s %15s %5s %15s %5s\n", \
size_array[s], sN, sSN, sSNp, sIPP, sIPPp); \ size_array[s], sN, sSN, sSNp, sIPP, sIPPp); \
} \ } \
free(resultNormal); free(resultSSENeon); free(resultIPP); \ free(resultNormal); free(resultOpt); free(resultIPP); \
} }
#endif // !__PRIMTEST_H_INCLUDED__ #endif // !__PRIMTEST_H_INCLUDED__

View File

@ -16,6 +16,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <winpr/sysinfo.h>
#include "prim_test.h" #include "prim_test.h"
#define FUNC_TEST_SIZE 65536 #define FUNC_TEST_SIZE 65536
@ -33,9 +34,10 @@ int test_add16s_func(void)
INT16 ALIGN(src1[FUNC_TEST_SIZE+3]), ALIGN(src2[FUNC_TEST_SIZE+3]), INT16 ALIGN(src1[FUNC_TEST_SIZE+3]), ALIGN(src2[FUNC_TEST_SIZE+3]),
ALIGN(d1[FUNC_TEST_SIZE+3]), ALIGN(d2[FUNC_TEST_SIZE+3]); ALIGN(d1[FUNC_TEST_SIZE+3]), ALIGN(d2[FUNC_TEST_SIZE+3]);
int failed = 0; int failed = 0;
#if defined(WITH_SSE2) || defined(WITH_IPP)
int i; int i;
#endif
char testStr[256]; char testStr[256];
UINT32 pflags = primitives_get_flags(primitives_get());
testStr[0] = '\0'; testStr[0] = '\0';
get_random_data(src1, sizeof(src1)); get_random_data(src1, sizeof(src1));
@ -43,8 +45,8 @@ int test_add16s_func(void)
memset(d1, 0, sizeof(d1)); memset(d1, 0, sizeof(d1));
memset(d2, 0, sizeof(d2)); memset(d2, 0, sizeof(d2));
general_add_16s(src1+1, src2+1, d1+1, FUNC_TEST_SIZE); general_add_16s(src1+1, src2+1, d1+1, FUNC_TEST_SIZE);
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSE3_AVAILABLE) if(IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE3"); strcat(testStr, " SSE3");
/* Aligned */ /* Aligned */
@ -70,7 +72,7 @@ int test_add16s_func(void)
} }
} }
} }
#endif /* i386 */ #endif
#ifdef WITH_IPP #ifdef WITH_IPP
strcat(testStr, " IPP"); strcat(testStr, " IPP");
ippsAdd_16s(src1+1, src2+1, d2+1, FUNC_TEST_SIZE); ippsAdd_16s(src1+1, src2+1, d2+1, FUNC_TEST_SIZE);
@ -91,8 +93,11 @@ int test_add16s_func(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(add16s_speed_test, INT16, INT16, dst=dst, STD_SPEED_TEST(add16s_speed_test, INT16, INT16, dst=dst,
TRUE, general_add_16s(src1, src2, dst, size), TRUE, general_add_16s(src1, src2, dst, size),
TRUE, sse3_add_16s(src1, src2, dst, size), PRIM_X86_SSE3_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse3_add_16s(src1, src2, dst, size), PF_SSE3_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ippsAdd_16s(src1, src2, dst, size)); TRUE, ippsAdd_16s(src1, src2, dst, size));
int test_add16s_speed(void) int test_add16s_speed(void)

View File

@ -15,6 +15,7 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#include <winpr/sysinfo.h>
#include "prim_test.h" #include "prim_test.h"
@ -110,7 +111,6 @@ int test_alphaComp_func(void)
UINT32 ALIGN(dst2u[DST_WIDTH*DST_HEIGHT+1]); UINT32 ALIGN(dst2u[DST_WIDTH*DST_HEIGHT+1]);
UINT32 ALIGN(dst3[DST_WIDTH*DST_HEIGHT]); UINT32 ALIGN(dst3[DST_WIDTH*DST_HEIGHT]);
int error = 0; int error = 0;
UINT32 pflags = primitives_get_flags(primitives_get());
char testStr[256]; char testStr[256];
UINT32 *ptr; UINT32 *ptr;
int i, x, y; int i, x, y;
@ -132,8 +132,8 @@ int test_alphaComp_func(void)
general_alphaComp_argb((const BYTE *) src1, 4*SRC1_WIDTH, general_alphaComp_argb((const BYTE *) src1, 4*SRC1_WIDTH,
(const BYTE *) src2, 4*SRC2_WIDTH, (const BYTE *) src2, 4*SRC2_WIDTH,
(BYTE *) dst1, 4*DST_WIDTH, TEST_WIDTH, TEST_HEIGHT); (BYTE *) dst1, 4*DST_WIDTH, TEST_WIDTH, TEST_HEIGHT);
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE2"); strcat(testStr, " SSE2");
sse2_alphaComp_argb((const BYTE *) src1, 4*SRC1_WIDTH, sse2_alphaComp_argb((const BYTE *) src1, 4*SRC1_WIDTH,
@ -165,8 +165,8 @@ int test_alphaComp_func(void)
x, y, s1, s2, c0, c1); x, y, s1, s2, c0, c1);
error = 1; error = 1;
} }
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
UINT32 c2 = *PIXEL(dst2a, 4*DST_WIDTH, x, y); UINT32 c2 = *PIXEL(dst2a, 4*DST_WIDTH, x, y);
if (colordist(c0, c2) > TOLERANCE) if (colordist(c0, c2) > TOLERANCE)
@ -203,12 +203,15 @@ int test_alphaComp_func(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(alphaComp_speed, BYTE, BYTE, int bytes = size*4, STD_SPEED_TEST(alphaComp_speed, BYTE, BYTE, int bytes __attribute__((unused)) = size*4,
TRUE, general_alphaComp_argb(src1, bytes, src2, bytes, dst, bytes, TRUE, general_alphaComp_argb(src1, bytes, src2, bytes, dst, bytes,
size, size), size, size),
#ifdef WITH_SSE2
TRUE, sse2_alphaComp_argb(src1, bytes, src2, bytes, dst, bytes, TRUE, sse2_alphaComp_argb(src1, bytes, src2, bytes, dst, bytes,
size, size), PRIM_X86_SSE2_AVAILABLE, size, size), PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
FALSE, dst=dst, 0, #else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ipp_alphaComp_argb(src1, bytes, src2, bytes, dst, bytes, TRUE, ipp_alphaComp_argb(src1, bytes, src2, bytes, dst, bytes,
size, size)); size, size));

View File

@ -15,6 +15,7 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#include <winpr/sysinfo.h>
#include "prim_test.h" #include "prim_test.h"
@ -39,7 +40,6 @@ int test_and_32u_func(void)
UINT32 ALIGN(src[FUNC_TEST_SIZE+3]), ALIGN(dst[FUNC_TEST_SIZE+3]); UINT32 ALIGN(src[FUNC_TEST_SIZE+3]), ALIGN(dst[FUNC_TEST_SIZE+3]);
int failed = 0; int failed = 0;
int i; int i;
UINT32 pflags = primitives_get_flags(primitives_get());
char testStr[256]; char testStr[256];
testStr[0] = '\0'; testStr[0] = '\0';
@ -55,8 +55,8 @@ int test_and_32u_func(void)
++failed; ++failed;
} }
} }
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSE3_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE3"); strcat(testStr, " SSE3");
/* Aligned */ /* Aligned */
@ -92,8 +92,11 @@ int test_and_32u_func(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(andC_32u_speed_test, UINT32, UINT32, dst=dst, STD_SPEED_TEST(andC_32u_speed_test, UINT32, UINT32, dst=dst,
TRUE, general_andC_32u(src1, constant, dst, size), TRUE, general_andC_32u(src1, constant, dst, size),
TRUE, sse3_andC_32u(src1, constant, dst, size), PRIM_X86_SSE3_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse3_andC_32u(src1, constant, dst, size), PF_SSE3_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ippsAndC_32u(src1, constant, dst, size)) TRUE, ippsAndC_32u(src1, constant, dst, size))
int test_and_32u_speed(void) int test_and_32u_speed(void)
@ -113,7 +116,6 @@ int test_or_32u_func(void)
UINT32 ALIGN(src[FUNC_TEST_SIZE+3]), ALIGN(dst[FUNC_TEST_SIZE+3]); UINT32 ALIGN(src[FUNC_TEST_SIZE+3]), ALIGN(dst[FUNC_TEST_SIZE+3]);
int failed = 0; int failed = 0;
int i; int i;
UINT32 pflags = primitives_get_flags(primitives_get());
char testStr[256]; char testStr[256];
testStr[0] = '\0'; testStr[0] = '\0';
@ -129,8 +131,8 @@ int test_or_32u_func(void)
++failed; ++failed;
} }
} }
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSE3_AVAILABLE) if(IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE3"); strcat(testStr, " SSE3");
/* Aligned */ /* Aligned */
@ -166,8 +168,11 @@ int test_or_32u_func(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(orC_32u_speed_test, UINT32, UINT32, dst=dst, STD_SPEED_TEST(orC_32u_speed_test, UINT32, UINT32, dst=dst,
TRUE, general_orC_32u(src1, constant, dst, size), TRUE, general_orC_32u(src1, constant, dst, size),
TRUE, sse3_orC_32u(src1, constant, dst, size), PRIM_X86_SSE3_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse3_orC_32u(src1, constant, dst, size), PF_SSE3_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ippsOrC_32u(src1, constant, dst, size)) TRUE, ippsOrC_32u(src1, constant, dst, size))
int test_or_32u_speed(void) int test_or_32u_speed(void)

View File

@ -16,6 +16,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <winpr/sysinfo.h>
#include "prim_test.h" #include "prim_test.h"
static const int RGB_TRIAL_ITERATIONS = 1000; static const int RGB_TRIAL_ITERATIONS = 1000;
@ -30,15 +31,19 @@ extern pstatus_t general_yCbCrToRGB_16s16s_P3P3(const INT16 *pSrc[3],
int srcStep, INT16 *pDst[3], int dstStep, const prim_size_t *roi); int srcStep, INT16 *pDst[3], int dstStep, const prim_size_t *roi);
extern pstatus_t sse2_yCbCrToRGB_16s16s_P3P3(const INT16 *pSrc[3], extern pstatus_t sse2_yCbCrToRGB_16s16s_P3P3(const INT16 *pSrc[3],
int srcStep, INT16 *pDst[3], int dstStep, const prim_size_t *roi); int srcStep, INT16 *pDst[3], int dstStep, const prim_size_t *roi);
extern pstatus_t neon_yCbCrToRGB_16s16s_P3P3(const INT16 *pSrc[3],
int srcStep, INT16 *pDst[3], int dstStep, const prim_size_t *roi);
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
int test_RGBToRGB_16s8u_P3AC4R_func(void) int test_RGBToRGB_16s8u_P3AC4R_func(void)
{ {
INT16 ALIGN(r[4096]), ALIGN(g[4096]), ALIGN(b[4096]); INT16 ALIGN(r[4096]), ALIGN(g[4096]), ALIGN(b[4096]);
UINT32 ALIGN(out1[4096]), ALIGN(out2[4096]); UINT32 ALIGN(out1[4096]);
#ifdef WITH_SSE2
UINT32 ALIGN(out2[4096]);
#endif
int i; int i;
int failed = 0; int failed = 0;
UINT32 pflags = primitives_get_flags(primitives_get());
char testStr[256]; char testStr[256];
INT16 *ptrs[3]; INT16 *ptrs[3];
prim_size_t roi = { 64, 64 }; prim_size_t roi = { 64, 64 };
@ -61,8 +66,8 @@ int test_RGBToRGB_16s8u_P3AC4R_func(void)
general_RGBToRGB_16s8u_P3AC4R((const INT16 **) ptrs, 64*2, general_RGBToRGB_16s8u_P3AC4R((const INT16 **) ptrs, 64*2,
(BYTE *) out1, 64*4, &roi); (BYTE *) out1, 64*4, &roi);
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE2"); strcat(testStr, " SSE2");
sse2_RGBToRGB_16s8u_P3AC4R((const INT16 **) ptrs, 64*2, sse2_RGBToRGB_16s8u_P3AC4R((const INT16 **) ptrs, 64*2,
@ -88,10 +93,13 @@ STD_SPEED_TEST(
rgb_to_argb_speed, INT16*, UINT32, dst=dst, rgb_to_argb_speed, INT16*, UINT32, dst=dst,
TRUE, general_RGBToRGB_16s8u_P3AC4R( TRUE, general_RGBToRGB_16s8u_P3AC4R(
(const INT16 **) src1, 64*2, (BYTE *) dst, 64*4, &roi64x64), (const INT16 **) src1, 64*2, (BYTE *) dst, 64*4, &roi64x64),
#ifdef WITH_SSE2
TRUE, sse2_RGBToRGB_16s8u_P3AC4R( TRUE, sse2_RGBToRGB_16s8u_P3AC4R(
(const INT16 **) src1, 64*2, (BYTE *) dst, 64*4, &roi64x64), (const INT16 **) src1, 64*2, (BYTE *) dst, 64*4, &roi64x64),
PRIM_X86_SSE2_AVAILABLE, PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
FALSE, dst=dst, 0, #else
FALSE, PRIM_NOP, 0, FALSE,
#endif
FALSE, dst=dst); FALSE, dst=dst);
int test_RGBToRGB_16s8u_P3AC4R_speed(void) int test_RGBToRGB_16s8u_P3AC4R_speed(void)
@ -131,7 +139,6 @@ int test_yCbCrToRGB_16s16s_P3P3_func(void)
INT16 ALIGN(r2[4096]), ALIGN(g2[4096]), ALIGN(b2[4096]); INT16 ALIGN(r2[4096]), ALIGN(g2[4096]), ALIGN(b2[4096]);
int i; int i;
int failed = 0; int failed = 0;
UINT32 pflags = primitives_get_flags(primitives_get());
char testStr[256]; char testStr[256];
const INT16 *in[3]; const INT16 *in[3];
INT16 *out1[3]; INT16 *out1[3];
@ -167,8 +174,8 @@ int test_yCbCrToRGB_16s16s_P3P3_func(void)
out2[2] = b2; out2[2] = b2;
general_yCbCrToRGB_16s16s_P3P3(in, 64*2, out1, 64*2, &roi); general_yCbCrToRGB_16s16s_P3P3(in, 64*2, out1, 64*2, &roi);
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE2"); strcat(testStr, " SSE2");
sse2_yCbCrToRGB_16s16s_P3P3(in, 64*2, out2, 64*2, &roi); sse2_yCbCrToRGB_16s16s_P3P3(in, 64*2, out2, 64*2, &roi);
@ -192,9 +199,15 @@ int test_yCbCrToRGB_16s16s_P3P3_func(void)
STD_SPEED_TEST( STD_SPEED_TEST(
ycbcr_to_rgb_speed, INT16*, INT16*, dst=dst, ycbcr_to_rgb_speed, INT16*, INT16*, dst=dst,
TRUE, general_yCbCrToRGB_16s16s_P3P3(src1, 64*2, dst, 64*2, &roi64x64), TRUE, general_yCbCrToRGB_16s16s_P3P3(src1, 64*2, dst, 64*2, &roi64x64),
#ifdef WITH_SSE2
TRUE, sse2_yCbCrToRGB_16s16s_P3P3(src1, 64*2, dst, 64*2, &roi64x64), TRUE, sse2_yCbCrToRGB_16s16s_P3P3(src1, 64*2, dst, 64*2, &roi64x64),
PRIM_X86_SSE2_AVAILABLE, PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
FALSE, dst=dst, 0, #elif defined(WITH_NEON)
TRUE, neon_yCbCrToRGB_16s16s_P3P3(src1, 64*2, dst, 64*2, &roi64x64),
PF_ARM_NEON_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
FALSE, dst=dst); FALSE, dst=dst);
int test_yCbCrToRGB_16s16s_P3P3_speed(void) int test_yCbCrToRGB_16s16s_P3P3_speed(void)

View File

@ -16,6 +16,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <winpr/sysinfo.h>
#include "prim_test.h" #include "prim_test.h"
static const int MEMCPY_PRETEST_ITERATIONS = 1000000; static const int MEMCPY_PRETEST_ITERATIONS = 1000000;
@ -70,8 +71,7 @@ int test_copy8u_func(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(copy8u_speed_test, BYTE, BYTE, dst=dst, STD_SPEED_TEST(copy8u_speed_test, BYTE, BYTE, dst=dst,
TRUE, memcpy(dst, src1, size), TRUE, memcpy(dst, src1, size),
FALSE, NULL, 0, FALSE, PRIM_NOP, 0, FALSE,
FALSE, NULL, 0,
TRUE, ippsCopy_8u(src1, dst, size)); TRUE, ippsCopy_8u(src1, dst, size));
int test_copy8u_speed(void) int test_copy8u_speed(void)

View File

@ -16,6 +16,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <winpr/sysinfo.h>
#include "prim_test.h" #include "prim_test.h"
static const int MEMSET8_PRETEST_ITERATIONS = 100000000; static const int MEMSET8_PRETEST_ITERATIONS = 100000000;
@ -36,16 +37,17 @@ static const int set_sizes[] = { 1, 4, 16, 32, 64, 256, 1024, 4096 };
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
int test_set8u_func(void) int test_set8u_func(void)
{ {
#if defined(WITH_SSE2) || defined(WITH_IPP)
BYTE ALIGN(dest[48]); BYTE ALIGN(dest[48]);
int failed = 0;
int off; int off;
#endif
int failed = 0;
char testStr[256]; char testStr[256];
UINT32 pflags = primitives_get_flags(primitives_get());
testStr[0] = '\0'; testStr[0] = '\0';
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
/* Test SSE under various alignments */ /* Test SSE under various alignments */
if (pflags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE2"); strcat(testStr, " SSE2");
for (off=0; off<16; ++off) for (off=0; off<16; ++off)
@ -101,8 +103,7 @@ int test_set8u_func(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(set8u_speed_test, BYTE, BYTE, dst=dst, STD_SPEED_TEST(set8u_speed_test, BYTE, BYTE, dst=dst,
TRUE, memset(dst, constant, size), TRUE, memset(dst, constant, size),
FALSE, NULL, 0, FALSE, PRIM_NOP, 0, FALSE,
FALSE, NULL, 0,
TRUE, ippsSet_8u(constant, dst, size)); TRUE, ippsSet_8u(constant, dst, size));
int test_set8u_speed(void) int test_set8u_speed(void)
@ -116,17 +117,17 @@ int test_set8u_speed(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
int test_set32s_func(void) int test_set32s_func(void)
{ {
primitives_t* prims = primitives_get(); #if defined(WITH_SSE2) || defined(WITH_IPP)
INT32 ALIGN(dest[512]); INT32 ALIGN(dest[512]);
int failed = 0;
int off; int off;
#endif
int failed = 0;
char testStr[256]; char testStr[256];
UINT32 pflags = primitives_get_flags(prims);
testStr[0] = '\0'; testStr[0] = '\0';
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
/* Test SSE under various alignments */ /* Test SSE under various alignments */
if (pflags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE2"); strcat(testStr, " SSE2");
for (off=0; off<16; ++off) { for (off=0; off<16; ++off) {
@ -179,17 +180,17 @@ int test_set32s_func(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
int test_set32u_func(void) int test_set32u_func(void)
{ {
primitives_t* prims = primitives_get(); #if defined(WITH_SSE2) || defined(WITH_IPP)
UINT32 ALIGN(dest[512]); UINT32 ALIGN(dest[512]);
int failed = 0;
int off; int off;
#endif
int failed = 0;
char testStr[256]; char testStr[256];
UINT32 pflags = primitives_get_flags(prims);
testStr[0] = '\0'; testStr[0] = '\0';
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
/* Test SSE under various alignments */ /* Test SSE under various alignments */
if (pflags & PRIM_X86_SSE2_AVAILABLE) if (IsProcessorFeaturePresent(PF_SSE2_INSTRUCTIONS_AVAILABLE))
{ {
strcat(testStr, " SSE2"); strcat(testStr, " SSE2");
for (off=0; off<16; ++off) { for (off=0; off<16; ++off) {
@ -251,8 +252,11 @@ static inline void memset32u_naive(
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(set32u_speed_test, UINT32, UINT32, dst=dst, STD_SPEED_TEST(set32u_speed_test, UINT32, UINT32, dst=dst,
TRUE, memset32u_naive(constant, dst, size), TRUE, memset32u_naive(constant, dst, size),
TRUE, sse2_set_32u(constant, dst, size), PRIM_X86_SSE2_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse2_set_32u(constant, dst, size), PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ipp_wrapper_set_32u(constant, dst, size)); TRUE, ipp_wrapper_set_32u(constant, dst, size));
int test_set32u_speed(void) int test_set32u_speed(void)
@ -280,8 +284,11 @@ static inline void memset32s_naive(
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(set32s_speed_test, INT32, INT32, dst=dst, STD_SPEED_TEST(set32s_speed_test, INT32, INT32, dst=dst,
TRUE, memset32s_naive(constant, dst, size), TRUE, memset32s_naive(constant, dst, size),
TRUE, sse2_set_32s(constant, dst, size), PRIM_X86_SSE2_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse2_set_32s(constant, dst, size), PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ippsSet_32s(constant, dst, size)); TRUE, ippsSet_32s(constant, dst, size));
int test_set32s_speed(void) int test_set32s_speed(void)

View File

@ -16,6 +16,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <winpr/sysinfo.h>
#include "prim_test.h" #include "prim_test.h"
#define FUNC_TEST_SIZE 65536 #define FUNC_TEST_SIZE 65536
@ -47,7 +48,7 @@ extern pstatus_t sse2_rShiftC_16u(
extern pstatus_t sse2_shiftC_16u( extern pstatus_t sse2_shiftC_16u(
const UINT16 *pSrc, int val, UINT16 *pDst, int len); const UINT16 *pSrc, int val, UINT16 *pDst, int len);
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
#define SHIFT_TEST_FUNC(_name_, _type_, _str_, _f1_, _f2_) \ #define SHIFT_TEST_FUNC(_name_, _type_, _str_, _f1_, _f2_) \
int _name_(void) \ int _name_(void) \
{ \ { \
@ -55,12 +56,11 @@ int _name_(void) \
ALIGN(d1[FUNC_TEST_SIZE+3]), ALIGN(d2[FUNC_TEST_SIZE+3]); \ ALIGN(d1[FUNC_TEST_SIZE+3]), ALIGN(d2[FUNC_TEST_SIZE+3]); \
int failed = 0; \ int failed = 0; \
int i; \ int i; \
UINT32 pflags = primitives_get_flags(primitives_get()); \
char testStr[256]; \ char testStr[256]; \
testStr[0] = '\0'; \ testStr[0] = '\0'; \
get_random_data(src, sizeof(src)); \ get_random_data(src, sizeof(src)); \
_f1_(src+1, 3, d1+1, FUNC_TEST_SIZE); \ _f1_(src+1, 3, d1+1, FUNC_TEST_SIZE); \
if (pflags & PRIM_X86_SSE3_AVAILABLE) \ if (IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) \
{ \ { \
strcat(testStr, " SSE3"); \ strcat(testStr, " SSE3"); \
/* Aligned */ \ /* Aligned */ \
@ -109,23 +109,35 @@ SHIFT_TEST_FUNC(test_rShift_16u_func, UINT16, "rshift_16u", general_rShiftC_16u,
/* ========================================================================= */ /* ========================================================================= */
STD_SPEED_TEST(speed_lShift_16s, INT16, INT16, dst=dst, STD_SPEED_TEST(speed_lShift_16s, INT16, INT16, dst=dst,
TRUE, general_lShiftC_16s(src1, constant, dst, size), TRUE, general_lShiftC_16s(src1, constant, dst, size),
TRUE, sse2_lShiftC_16s(src1, constant, dst, size), PRIM_X86_SSE2_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse2_lShiftC_16s(src1, constant, dst, size), PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ippsLShiftC_16s(src1, constant, dst, size)); TRUE, ippsLShiftC_16s(src1, constant, dst, size));
STD_SPEED_TEST(speed_lShift_16u, UINT16, UINT16, dst=dst, STD_SPEED_TEST(speed_lShift_16u, UINT16, UINT16, dst=dst,
TRUE, general_lShiftC_16u(src1, constant, dst, size), TRUE, general_lShiftC_16u(src1, constant, dst, size),
TRUE, sse2_lShiftC_16u(src1, constant, dst, size), PRIM_X86_SSE2_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse2_lShiftC_16u(src1, constant, dst, size), PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ippsLShiftC_16u(src1, constant, dst, size)); TRUE, ippsLShiftC_16u(src1, constant, dst, size));
STD_SPEED_TEST(speed_rShift_16s, INT16, INT16, dst=dst, STD_SPEED_TEST(speed_rShift_16s, INT16, INT16, dst=dst,
TRUE, general_rShiftC_16s(src1, constant, dst, size), TRUE, general_rShiftC_16s(src1, constant, dst, size),
TRUE, sse2_rShiftC_16s(src1, constant, dst, size), PRIM_X86_SSE2_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse2_rShiftC_16s(src1, constant, dst, size), PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ippsRShiftC_16s(src1, constant, dst, size)); TRUE, ippsRShiftC_16s(src1, constant, dst, size));
STD_SPEED_TEST(speed_rShift_16u, UINT16, UINT16, dst=dst, STD_SPEED_TEST(speed_rShift_16u, UINT16, UINT16, dst=dst,
TRUE, general_rShiftC_16u(src1, constant, dst, size), TRUE, general_rShiftC_16u(src1, constant, dst, size),
TRUE, sse2_rShiftC_16u(src1, constant, dst, size), PRIM_X86_SSE2_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, sse2_rShiftC_16u(src1, constant, dst, size), PF_SSE2_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
TRUE, ippsRShiftC_16u(src1, constant, dst, size)); TRUE, ippsRShiftC_16u(src1, constant, dst, size));
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */

View File

@ -16,29 +16,34 @@
#include "config.h" #include "config.h"
#endif #endif
#include <winpr/sysinfo.h>
#include "prim_test.h" #include "prim_test.h"
static const int SIGN_PRETEST_ITERATIONS = 100000; static const int SIGN_PRETEST_ITERATIONS = 100000;
static const float TEST_TIME = 1.0; static const float TEST_TIME = 1.0;
extern pstatus_t general_sign_16s(const INT16 *pSrc, INT16 *pDst, int len); extern pstatus_t general_sign_16s(const INT16 *pSrc, INT16 *pDst, int len);
#ifdef WITH_SSE2
extern pstatus_t ssse3_sign_16s(const INT16 *pSrc, INT16 *pDst, int len); extern pstatus_t ssse3_sign_16s(const INT16 *pSrc, INT16 *pDst, int len);
#endif
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
int test_sign16s_func(void) int test_sign16s_func(void)
{ {
INT16 ALIGN(src[65535]), ALIGN(d1[65535]), ALIGN(d2[65535]); INT16 ALIGN(src[65535]), ALIGN(d1[65535]);
int failed = 0; #ifdef WITH_SSE2
INT16 ALIGN(d2[65535]);
int i; int i;
UINT32 pflags = primitives_get_flags(primitives_get()); #endif
int failed = 0;
char testStr[256]; char testStr[256];
/* Test when we can reach 16-byte alignment */ /* Test when we can reach 16-byte alignment */
testStr[0] = '\0'; testStr[0] = '\0';
get_random_data(src, sizeof(src)); get_random_data(src, sizeof(src));
general_sign_16s(src+1, d1+1, 65535); general_sign_16s(src+1, d1+1, 65535);
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSSE3_AVAILABLE) if (IsProcessorFeaturePresentEx(PF_EX_SSSE3))
{ {
strcat(testStr, " SSSE3"); strcat(testStr, " SSSE3");
ssse3_sign_16s(src+1, d2+1, 65535); ssse3_sign_16s(src+1, d2+1, 65535);
@ -57,8 +62,8 @@ int test_sign16s_func(void)
/* Test when we cannot reach 16-byte alignment */ /* Test when we cannot reach 16-byte alignment */
get_random_data(src, sizeof(src)); get_random_data(src, sizeof(src));
general_sign_16s(src+1, d1+2, 65535); general_sign_16s(src+1, d1+2, 65535);
#ifdef _M_IX86_AMD64 #ifdef WITH_SSE2
if (pflags & PRIM_X86_SSSE3_AVAILABLE) if (IsProcessorFeaturePresentEx(PF_EX_SSSE3))
{ {
ssse3_sign_16s(src+1, d2+2, 65535); ssse3_sign_16s(src+1, d2+2, 65535);
for (i=2; i<65535; ++i) for (i=2; i<65535; ++i)
@ -79,8 +84,11 @@ int test_sign16s_func(void)
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
STD_SPEED_TEST(sign16s_speed_test, INT16, INT16, dst=dst, STD_SPEED_TEST(sign16s_speed_test, INT16, INT16, dst=dst,
TRUE, general_sign_16s(src1, dst, size), TRUE, general_sign_16s(src1, dst, size),
TRUE, ssse3_sign_16s(src1, dst, size), PRIM_X86_SSSE3_AVAILABLE, #ifdef WITH_SSE2
FALSE, dst=dst, 0, TRUE, ssse3_sign_16s(src1, dst, size), PF_EX_SSSE3, TRUE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
FALSE, dst=dst); FALSE, dst=dst);
int test_sign16s_speed(void) int test_sign16s_speed(void)

View File

@ -25,20 +25,23 @@ FIND_LIBRARY(CORE_GRAPHICS CoreGraphics)
FIND_LIBRARY(APP_SERVICES ApplicationServices) FIND_LIBRARY(APP_SERVICES ApplicationServices)
FIND_LIBRARY(IOKIT IOKit) FIND_LIBRARY(IOKIT IOKit)
FIND_LIBRARY(IOSURFACE IOSurface) FIND_LIBRARY(IOSURFACE IOSurface)
FIND_LIBRARY(CARBON Carbon)
set(${MODULE_PREFIX}_SRCS set(${MODULE_PREFIX}_SRCS
mfreerdp.c mfreerdp.c
mfreerdp.h mfreerdp.h
mf_interface.c mf_interface.c
mf_interface.h mf_interface.h
mf_event.c mf_event.c
mf_event.h mf_event.h
mf_peer.c mf_peer.c
mf_peer.h mf_peer.h
mf_info.c mf_info.c
mf_info.h mf_info.h
mf_mountain_lion.c mf_input.c
mf_mountain_lion.h) mf_input.h
mf_mountain_lion.c
mf_mountain_lion.h)
if(CHANNEL_AUDIN_SERVER) if(CHANNEL_AUDIN_SERVER)
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS}
@ -57,13 +60,14 @@ add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS}
freerdp-server freerdp-server
${AUDIO_TOOL} ${AUDIO_TOOL}
${CORE_AUDIO} ${CORE_AUDIO}
${CORE_VIDEO} ${CORE_VIDEO}
${CORE_GRAPHICS} ${CORE_GRAPHICS}
${APP_SERVICES} ${APP_SERVICES}
${IOKIT} ${IOKIT}
${IOSURFACE}) ${IOSURFACE}
${CARBON})
set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS
MONOLITHIC ${MONOLITHIC_BUILD} MONOLITHIC ${MONOLITHIC_BUILD}

620
server/Mac/mf_input.c Normal file
View File

@ -0,0 +1,620 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* FreeRDP Mac OS X Server (Input)
*
* Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <ApplicationServices/ApplicationServices.h>
#include <Carbon/Carbon.h>
#include <winpr/windows.h>
#include "mf_input.h"
#include "mf_info.h"
static const CGKeyCode keymap[256] = {
0xFF, //0x0
kVK_Escape, //0x1
kVK_ANSI_1, //0x2
kVK_ANSI_2, //0x3
kVK_ANSI_3, //0x4
kVK_ANSI_4, //0x5
kVK_ANSI_5, //0x6
kVK_ANSI_6, //0x7
kVK_ANSI_7, //0x8
kVK_ANSI_8, //0x9
kVK_ANSI_9, //0xa
kVK_ANSI_0, //0xb
kVK_ANSI_Minus, //0xc
kVK_ANSI_Equal, //0xd
kVK_Delete, //0xe
kVK_Tab, //0xf
kVK_ANSI_Q, //0x10
kVK_ANSI_W, //0x11
kVK_ANSI_E, //0x12
kVK_ANSI_R, //0x13
kVK_ANSI_T, //0x14
kVK_ANSI_Y, //0x15
kVK_ANSI_U, //0x16
kVK_ANSI_I, //0x17
kVK_ANSI_O, //0x18
kVK_ANSI_P, //0x19
kVK_ANSI_LeftBracket, //0x1a
kVK_ANSI_RightBracket, //0x1b
kVK_Return, //0x1c
kVK_Control, //0x1d
kVK_ANSI_A, //0x1e
kVK_ANSI_S, //0x1f
kVK_ANSI_D, //0x20
kVK_ANSI_F, //0x21
kVK_ANSI_G, //0x22
kVK_ANSI_H, //0x23
kVK_ANSI_J, //0x24
kVK_ANSI_K, //0x25
kVK_ANSI_L, //0x26
kVK_ANSI_Semicolon, //0x27
kVK_ANSI_Quote, //0x28
kVK_ANSI_Grave, //0x29
kVK_Shift, //0x2a
kVK_ANSI_Backslash, //0x2b
kVK_ANSI_Z, //0x2c
kVK_ANSI_X, //0x2d
kVK_ANSI_C, //0x2e
kVK_ANSI_V, //0x2f
kVK_ANSI_B, //0x30
kVK_ANSI_N, //0x31
kVK_ANSI_M, //0x32
kVK_ANSI_Comma, //0x33
kVK_ANSI_Period, //0x34
kVK_ANSI_Slash, //0x35
kVK_Shift, //0x36
kVK_ANSI_KeypadMultiply, //0x37
kVK_Option, //0x38
kVK_Space, //0x39
kVK_CapsLock, //0x3a
kVK_F1, //0x3b
kVK_F2, //0x3c
kVK_F3, //0x3d
kVK_F4, //0x3e
kVK_F5, //0x3f
kVK_F6, //0x40
kVK_F7, //0x41
kVK_F8, //0x42
kVK_F9, //0x43
kVK_F10, //0x44
0xFF, //0x45 -- numlock
0xFF, //0x46 -- scroll lock
kVK_ANSI_Keypad7, //0x47
kVK_ANSI_Keypad8, //0x48
kVK_ANSI_Keypad9, //0x49
kVK_ANSI_KeypadMinus, //0x4a
kVK_ANSI_Keypad4, //0x4b
kVK_ANSI_Keypad5, //0x4c
kVK_ANSI_Keypad6, //0x4d
kVK_ANSI_KeypadPlus, //0x4e
kVK_ANSI_Keypad1, //0x4f
kVK_ANSI_Keypad2, //0x50
kVK_ANSI_Keypad3, //0x51
kVK_ANSI_Keypad0, //0x52
kVK_ANSI_KeypadDecimal, //0x53
0xFF, //0x54
0xFF, //0x55
0xFF, //0x56
kVK_F11, //0x57
kVK_F12, //0x58
0xFF, //0x59 -- pause
0xFF, //0x5a
kVK_Control, //0x5b
kVK_Control, //0x5c
0xFF, //0x5d -- application
0xFF, //0x5e -- power
0xFF, //0x5f -- sleep
0xFF, //0x60
0xFF, //0x61
0xFF, //0x62
0xFF, //0x63 -- wake
0xFF, //0x64
0xFF, //0x65
0xFF, //0x66
0xFF, //0x67
0xFF, //0x68
0xFF, //0x69
0xFF, //0x6a
0xFF, //0x6b
0xFF, //0x6c
0xFF, //0x6d
0xFF, //0x6e
0xFF, //0x6f
0xFF, //0x70
0xFF, //0x71
0xFF, //0x72
0xFF, //0x73
0xFF, //0x74
0xFF, //0x75
0xFF, //0x76
0xFF, //0x77
0xFF, //0x78
0xFF, //0x79
0xFF, //0x7a
0xFF, //0x7b
0xFF, //0x7c
0xFF, //0x7d
0xFF, //0x7e
0xFF, //0x7f
0xFF, //0x80
0xFF, //0x81
0xFF, //0x82
0xFF, //0x83
0xFF, //0x84
0xFF, //0x85
0xFF, //0x86
0xFF, //0x87
0xFF, //0x88
0xFF, //0x89
0xFF, //0x8a
0xFF, //0x8b
0xFF, //0x8c
0xFF, //0x8d
0xFF, //0x8e
0xFF, //0x8f
0xFF, //0x90
0xFF, //0x91
0xFF, //0x92
0xFF, //0x93
0xFF, //0x94
0xFF, //0x95
0xFF, //0x96
0xFF, //0x97
0xFF, //0x98
0xFF, //0x99
0xFF, //0x9a
0xFF, //0x9b
0xFF, //0x9c
0xFF, //0x9d
0xFF, //0x9e
0xFF, //0x9f
0xFF, //0xa0
0xFF, //0xa1
0xFF, //0xa2
0xFF, //0xa3
0xFF, //0xa4
0xFF, //0xa5
0xFF, //0xa6
0xFF, //0xa7
0xFF, //0xa8
0xFF, //0xa9
0xFF, //0xaa
0xFF, //0xab
0xFF, //0xac
0xFF, //0xad
0xFF, //0xae
0xFF, //0xaf
0xFF, //0xb0
0xFF, //0xb1
0xFF, //0xb2
0xFF, //0xb3
0xFF, //0xb4
0xFF, //0xb5
0xFF, //0xb6
0xFF, //0xb7
0xFF, //0xb8
0xFF, //0xb9
0xFF, //0xba
0xFF, //0xbb
0xFF, //0xbc
0xFF, //0xbd
0xFF, //0xbe
0xFF, //0xbf
0xFF, //0xc0
0xFF, //0xc1
0xFF, //0xc2
0xFF, //0xc3
0xFF, //0xc4
0xFF, //0xc5
0xFF, //0xc6
0xFF, //0xc7
0xFF, //0xc8
0xFF, //0xc9
0xFF, //0xca
0xFF, //0xcb
0xFF, //0xcc
0xFF, //0xcd
0xFF, //0xce
0xFF, //0xcf
0xFF, //0xd0
0xFF, //0xd1
0xFF, //0xd2
0xFF, //0xd3
0xFF, //0xd4
0xFF, //0xd5
0xFF, //0xd6
0xFF, //0xd7
0xFF, //0xd8
0xFF, //0xd9
0xFF, //0xda
0xFF, //0xdb
0xFF, //0xdc
0xFF, //0xdd
0xFF, //0xde
0xFF, //0xdf
0xFF, //0xe0
0xFF, //0xe1
0xFF, //0xe2
0xFF, //0xe3
0xFF, //0xe4
0xFF, //0xe5
0xFF, //0xe6
0xFF, //0xe7
0xFF, //0xe8
0xFF, //0xe9
0xFF, //0xea
0xFF, //0xeb
0xFF, //0xec
0xFF, //0xed
0xFF, //0xee
0xFF, //0xef
0xFF, //0xf0
0xFF, //0xf1
0xFF, //0xf2
0xFF, //0xf3
0xFF, //0xf4
0xFF, //0xf5
0xFF, //0xf6
0xFF, //0xf7
0xFF, //0xf8
0xFF, //0xf9
0xFF, //0xfa
0xFF, //0xfb
0xFF, //0xfc
0xFF, //0xfd
0xFF, //0xfe
};
void mf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
{
CGEventSourceRef source = CGEventSourceCreate (kCGEventSourceStateHIDSystemState);
BOOL keyDown = TRUE;
CGEventRef kbEvent;
CGKeyCode kCode = 0xFF;
if (flags & KBD_FLAGS_RELEASE)
{
keyDown = FALSE;
}
if (flags & KBD_FLAGS_EXTENDED)
{
switch (code) {
//case 0x52: //insert
case 0x53:
kCode = kVK_ForwardDelete;
break;
case 0x4B:
kCode = kVK_LeftArrow;
break;
case 0x47:
kCode = kVK_Home;
break;
case 0x4F:
kCode = kVK_End;
break;
case 0x48:
kCode = kVK_UpArrow;
break;
case 0x50:
kCode = kVK_DownArrow;
break;
case 0x49:
kCode = kVK_PageUp;
break;
case 0x51:
kCode = kVK_PageDown;
break;
case 0x4D:
kCode = kVK_RightArrow;
break;
default:
break;
}
}
else
{
kCode = keymap[code];
}
kbEvent = CGEventCreateKeyboardEvent(source, kCode, keyDown);
CGEventPost(kCGHIDEventTap, kbEvent);
CFRelease(kbEvent);
CFRelease(source);
/*
if (flags & KBD_FLAGS_EXTENDED)
printf("extended ");
printf("keypress: down = %d, SCAN=%#0X, VK=%#0X\n", keyDown, code, keymap[code]);
*/
}
void mf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
{
/*
INPUT keyboard_event;
keyboard_event.type = INPUT_KEYBOARD;
keyboard_event.ki.wVk = 0;
keyboard_event.ki.wScan = code;
keyboard_event.ki.dwFlags = KEYEVENTF_UNICODE;
keyboard_event.ki.dwExtraInfo = 0;
keyboard_event.ki.time = 0;
if (flags & KBD_FLAGS_RELEASE)
keyboard_event.ki.dwFlags |= KEYEVENTF_KEYUP;
SendInput(1, &keyboard_event, sizeof(INPUT));
*/
}
void mf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
float width, height;
CGWheelCount wheelCount = 2;
UINT32 scroll_x = 0;
UINT32 scroll_y = 0;
if (flags & PTR_FLAGS_WHEEL)
{
scroll_y = flags & WheelRotationMask;
if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
{
scroll_y = -(flags & WheelRotationMask) / 392;
}
else
{
scroll_y = (flags & WheelRotationMask) / 120;
}
CGEventSourceRef source = CGEventSourceCreate (kCGEventSourceStateHIDSystemState);
CGEventRef scroll = CGEventCreateScrollWheelEvent(source,
kCGScrollEventUnitLine,
wheelCount,
scroll_y,
scroll_x);
CGEventPost(kCGHIDEventTap, scroll);
CFRelease(scroll);
CFRelease(source);
}
/*
///////////////////////////////////////////////
// We dont support horizontal scrolling yet...
///////////////////////////////////////////////
else if (flags & PTR_FLAGS_)
{
scroll_y = flags & WheelRotationMask;
if (flags & PTR_FLAGS_WHEEL_NEGATIVE)
{
scroll_y = -(flags & WheelRotationMask) / 392;
}
else
{
scroll_y = (flags & WheelRotationMask) / 120;
}
CGEventSourceRef source = CGEventSourceCreate (kCGEventSourceStateCombinedSessionState);
CGEventRef scroll = CGEventCreateScrollWheelEvent(source,
kCGScrollEventUnitLine,
wheelCount,
scroll_y,
scroll_x);
CGEventPost(kCGHIDEventTap, scroll);
CFRelease(scroll);
CFRelease(source);
} */
else
{
mfInfo * mfi;
CGEventSourceRef source = CGEventSourceCreate (kCGEventSourceStateHIDSystemState);
CGEventType mouseType = kCGEventNull;
CGMouseButton mouseButton = kCGMouseButtonLeft;
mfi = mf_info_get_instance();
//width and height of primary screen (even in multimon setups
width = (float) mfi->servscreen_width;
height = (float) mfi->servscreen_height;
x += mfi->servscreen_xoffset;
y += mfi->servscreen_yoffset;
if (flags & PTR_FLAGS_MOVE)
{
if (mfi->mouse_down_left == TRUE)
{
mouseType = kCGEventLeftMouseDragged;
}
else if (mfi->mouse_down_right == TRUE)
{
mouseType = kCGEventRightMouseDragged;
}
else if (mfi->mouse_down_other == TRUE)
{
mouseType = kCGEventOtherMouseDragged;
}
else
{
mouseType = kCGEventMouseMoved;
}
CGEventRef move = CGEventCreateMouseEvent(source,
mouseType,
CGPointMake(x, y),
mouseButton // ignored for just movement
);
CGEventPost(kCGHIDEventTap, move);
CFRelease(move);
}
if (flags & PTR_FLAGS_BUTTON1)
{
mouseButton = kCGMouseButtonLeft;
if (flags & PTR_FLAGS_DOWN)
{
mouseType = kCGEventLeftMouseDown;
mfi->mouse_down_left = TRUE;
}
else
{
mouseType = kCGEventLeftMouseUp;
mfi->mouse_down_right = FALSE;
}
}
else if (flags & PTR_FLAGS_BUTTON2)
{
mouseButton = kCGMouseButtonRight;
if (flags & PTR_FLAGS_DOWN)
{
mouseType = kCGEventRightMouseDown;
mfi->mouse_down_right = TRUE;
}
else
{
mouseType = kCGEventRightMouseUp;
mfi->mouse_down_right = FALSE;
}
}
else if (flags & PTR_FLAGS_BUTTON3)
{
mouseButton = kCGMouseButtonCenter;
if (flags & PTR_FLAGS_DOWN)
{
mouseType = kCGEventOtherMouseDown;
mfi->mouse_down_other = TRUE;
}
else
{
mouseType = kCGEventOtherMouseUp;
mfi->mouse_down_other = FALSE;
}
}
CGEventRef mouseEvent = CGEventCreateMouseEvent(source,
mouseType,
CGPointMake(x, y),
mouseButton
);
CGEventPost(kCGHIDEventTap, mouseEvent);
CFRelease(mouseEvent);
CFRelease(source);
}
}
void mf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
printf("Unhandled mouse event!!!\n");
/*
if ((flags & PTR_XFLAGS_BUTTON1) || (flags & PTR_XFLAGS_BUTTON2))
{
INPUT mouse_event;
ZeroMemory(&mouse_event, sizeof(INPUT));
mouse_event.type = INPUT_MOUSE;
if (flags & PTR_FLAGS_MOVE)
{
float width, height;
wfInfo * wfi;
wfi = wf_info_get_instance();
//width and height of primary screen (even in multimon setups
width = (float) GetSystemMetrics(SM_CXSCREEN);
height = (float) GetSystemMetrics(SM_CYSCREEN);
x += wfi->servscreen_xoffset;
y += wfi->servscreen_yoffset;
//mouse_event.mi.dx = x * (0xFFFF / width);
//mouse_event.mi.dy = y * (0xFFFF / height);
mouse_event.mi.dx = (LONG) ((float) x * (65535.0f / width));
mouse_event.mi.dy = (LONG) ((float) y * (65535.0f / height));
mouse_event.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
SendInput(1, &mouse_event, sizeof(INPUT));
}
mouse_event.mi.dx = mouse_event.mi.dy = mouse_event.mi.dwFlags = 0;
if (flags & PTR_XFLAGS_DOWN)
mouse_event.mi.dwFlags |= MOUSEEVENTF_XDOWN;
else
mouse_event.mi.dwFlags |= MOUSEEVENTF_XUP;
if (flags & PTR_XFLAGS_BUTTON1)
mouse_event.mi.mouseData = XBUTTON1;
else if (flags & PTR_XFLAGS_BUTTON2)
mouse_event.mi.mouseData = XBUTTON2;
SendInput(1, &mouse_event, sizeof(INPUT));
}
else
{
mf_input_mouse_event(input, flags, x, y);
}
*/
}
void mf_input_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
{
}
void mf_input_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code)
{
}
void mf_input_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
}
void mf_input_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{
}

36
server/Mac/mf_input.h Normal file
View File

@ -0,0 +1,36 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* FreeRDP Mac OS X Server (Input)
*
* Copyright 2013 Corey Clayton <can.of.tuna@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MF_INPUT_H
#define MF_INPUT_H
#include "mf_interface.h"
void mf_input_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
void mf_input_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code);
void mf_input_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
void mf_input_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
//dummy versions
void mf_input_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code);
void mf_input_unicode_keyboard_event_dummy(rdpInput* input, UINT16 flags, UINT16 code);
void mf_input_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
void mf_input_extended_mouse_event_dummy(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y);
#endif /* MF_INPUT_H */

View File

@ -83,34 +83,20 @@ struct mf_info
UINT32 servscreen_xoffset; UINT32 servscreen_xoffset;
UINT32 servscreen_yoffset; UINT32 servscreen_yoffset;
//int frame_idx;
int bitsPerPixel; int bitsPerPixel;
//HDC driverDC;
int peerCount; int peerCount;
int activePeerCount; int activePeerCount;
//void* changeBuffer;
int framesPerSecond; int framesPerSecond;
//LPTSTR deviceKey;
//TCHAR deviceName[32];
freerdp_peer** peers; freerdp_peer** peers;
//BOOL mirrorDriverActive;
unsigned int framesWaiting; unsigned int framesWaiting;
UINT32 scale; UINT32 scale;
//HANDLE snd_mutex;
//BOOL snd_stop;
RFX_RECT invalid; RFX_RECT invalid;
pthread_mutex_t mutex; pthread_mutex_t mutex;
//BOOL updatePending;
//HANDLE updateEvent;
//HANDLE updateThread;
//HANDLE updateSemaphore;
//RFX_CONTEXT* rfx_context;
//unsigned long lastUpdate;
//unsigned long nextUpdate;
//SURFACE_BITS_COMMAND cmd;
BOOL mouse_down_left;
BOOL mouse_down_right;
BOOL mouse_down_other;
BOOL input_disabled; BOOL input_disabled;
BOOL force_all_disconnect; BOOL force_all_disconnect;
}; };

View File

@ -29,6 +29,7 @@
#include "mf_peer.h" #include "mf_peer.h"
#include "mf_info.h" #include "mf_info.h"
#include "mf_input.h"
#include "mf_event.h" #include "mf_event.h"
#include "mf_rdpsnd.h" #include "mf_rdpsnd.h"
@ -288,6 +289,10 @@ BOOL mf_peer_post_connect(freerdp_peer* client)
client->update->DesktopResize(client->update->context); client->update->DesktopResize(client->update->context);
mfi->mouse_down_left = FALSE;
mfi->mouse_down_right = FALSE;
mfi->mouse_down_other = FALSE;
//#ifdef WITH_SERVER_CHANNELS //#ifdef WITH_SERVER_CHANNELS
/* Iterate all channel names requested by the client and activate those supported by the server */ /* Iterate all channel names requested by the client and activate those supported by the server */
@ -373,7 +378,7 @@ void mf_peer_unicode_keyboard_event(rdpInput* input, UINT16 flags, UINT16 code)
printf("Client sent a unicode keyboard event (flags:0x%04X code:0x%04X)\n", flags, code); printf("Client sent a unicode keyboard event (flags:0x%04X code:0x%04X)\n", flags, code);
} }
void mf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y) /*void mf_peer_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT16 y)
{ {
//printf("Client sent a mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y); //printf("Client sent a mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y);
} }
@ -382,7 +387,7 @@ void mf_peer_extended_mouse_event(rdpInput* input, UINT16 flags, UINT16 x, UINT1
{ {
//printf("Client sent an extended mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y); //printf("Client sent an extended mouse event (flags:0x%04X pos: %d,%d)\n", flags, x, y);
} }
*/
/*static void mf_peer_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* areas) /*static void mf_peer_refresh_rect(rdpContext* context, BYTE count, RECTANGLE_16* areas)
{ {
BYTE i; BYTE i;
@ -507,10 +512,10 @@ void* mf_peer_main_loop(void* arg)
client->Activate = mf_peer_activate; client->Activate = mf_peer_activate;
client->input->SynchronizeEvent = mf_peer_synchronize_event; client->input->SynchronizeEvent = mf_peer_synchronize_event;
client->input->KeyboardEvent = mf_peer_keyboard_event; client->input->KeyboardEvent = mf_input_keyboard_event;//mf_peer_keyboard_event;
client->input->UnicodeKeyboardEvent = mf_peer_unicode_keyboard_event; client->input->UnicodeKeyboardEvent = mf_peer_unicode_keyboard_event;
client->input->MouseEvent = mf_peer_mouse_event; client->input->MouseEvent = mf_input_mouse_event;
client->input->ExtendedMouseEvent = mf_peer_extended_mouse_event; client->input->ExtendedMouseEvent = mf_input_extended_mouse_event;
//client->update->RefreshRect = mf_peer_refresh_rect; //client->update->RefreshRect = mf_peer_refresh_rect;
client->update->SuppressOutput = mf_peer_suppress_output; client->update->SuppressOutput = mf_peer_suppress_output;

View File

@ -88,6 +88,7 @@ int wf_info_try_lock(wfInfo* wfi, DWORD dwMilliseconds)
int wf_info_unlock(wfInfo* wfi) int wf_info_unlock(wfInfo* wfi)
{ {
if (ReleaseMutex(wfi->mutex) == 0) if (ReleaseMutex(wfi->mutex) == 0)
{ {
printf("wf_info_unlock failed with 0x%08X\n", GetLastError()); printf("wf_info_unlock failed with 0x%08X\n", GetLastError());
@ -125,8 +126,8 @@ wfInfo* wf_info_init()
_tprintf(_T("CreateMutex error: %d\n"), GetLastError()); _tprintf(_T("CreateMutex error: %d\n"), GetLastError());
} }
wfi->updateEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //wfi->updateEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
printf("updateEvent created\n"); //printf("updateEvent created\n");
wfi->updateSemaphore = CreateSemaphore(NULL, 0, 32, NULL); wfi->updateSemaphore = CreateSemaphore(NULL, 0, 32, NULL);

View File

@ -81,7 +81,8 @@ DWORD WINAPI wf_update_thread(LPVOID lpParam)
for (index = 0; index < wfi->activePeerCount; index++) for (index = 0; index < wfi->activePeerCount; index++)
{ {
//printf("Waiting for %d of %d\n", index + 1, wfi->activePeerCount); //printf("Waiting for %d of %d\n", index + 1, wfi->activePeerCount);
WaitForSingleObject(wfi->updateSemaphore, INFINITE); //WaitForSingleObject(wfi->updateSemaphore, INFINITE);
WaitForSingleObject(wfi->updateSemaphore, 1000);
} }
//printf("End of parallel sending\n"); //printf("End of parallel sending\n");
@ -202,7 +203,6 @@ void wf_update_encoder_reset(wfInfo* wfi)
wfi->rfx_context->width = wfi->servscreen_width; wfi->rfx_context->width = wfi->servscreen_width;
wfi->rfx_context->height = wfi->servscreen_height; wfi->rfx_context->height = wfi->servscreen_height;
rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8); rfx_context_set_pixel_format(wfi->rfx_context, RDP_PIXEL_FORMAT_B8G8R8A8);
rfx_context_set_cpu_opt(wfi->rfx_context, CPU_SSE2);
wfi->s = stream_new(0xFFFF); wfi->s = stream_new(0xFFFF);
} }

View File

@ -268,7 +268,7 @@ DWORD WINAPI wf_rdpsnd_wasapi_thread(LPVOID lpParam)
Sleep(hnsActualDuration/REFTIMES_PER_MILLISEC/2); Sleep(hnsActualDuration/REFTIMES_PER_MILLISEC/2);
hr = pCaptureClient->lpVtbl->GetNextPacketSize(pCaptureClient, &packetLength); hr = pCaptureClient->lpVtbl->GetNextPacketSize(pCaptureClient, &packetLength);
if (FAILED(hr)) if (FAILED(hr))
{ {

View File

@ -128,11 +128,18 @@ typedef VOID (*PTP_WORK_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context,
typedef VOID (*PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_TIMER Timer); typedef VOID (*PTP_TIMER_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_TIMER Timer);
typedef VOID (*PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WAIT Wait, TP_WAIT_RESULT WaitResult); typedef VOID (*PTP_WAIT_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PTP_WAIT Wait, TP_WAIT_RESULT WaitResult);
#endif
/* Non-Windows and pre Vista */
#if ((!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600)))
typedef VOID (*PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PVOID Overlapped, typedef VOID (*PTP_WIN32_IO_CALLBACK)(PTP_CALLBACK_INSTANCE Instance, PVOID Context, PVOID Overlapped,
ULONG IoResult, ULONG_PTR NumberOfBytesTransferred, PTP_IO Io); ULONG IoResult, ULONG_PTR NumberOfBytesTransferred, PTP_IO Io);
#endif #endif
/* Synch */ /* Synch */
WINPR_API PTP_WAIT CreateThreadpoolWait(PTP_WAIT_CALLBACK pfnwa, PVOID pv, PTP_CALLBACK_ENVIRON pcbe); WINPR_API PTP_WAIT CreateThreadpoolWait(PTP_WAIT_CALLBACK pfnwa, PVOID pv, PTP_CALLBACK_ENVIRON pcbe);

View File

@ -66,35 +66,6 @@
#define PROCESSOR_ARM_7TDMI 70001 #define PROCESSOR_ARM_7TDMI 70001
#define PROCESSOR_OPTIL 0x494F #define PROCESSOR_OPTIL 0x494F
#define PF_FLOATING_POINT_PRECISION_ERRATA 0
#define PF_FLOATING_POINT_EMULATED 1
#define PF_COMPARE_EXCHANGE_DOUBLE 2
#define PF_MMX_INSTRUCTIONS_AVAILABLE 3
#define PF_PPC_MOVEMEM_64BIT_OK 4
#define PF_ALPHA_BYTE_INSTRUCTIONS 5
#define PF_XMMI_INSTRUCTIONS_AVAILABLE 6
#define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7
#define PF_RDTSC_INSTRUCTION_AVAILABLE 8
#define PF_PAE_ENABLED 9
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
#define PF_SSE_DAZ_MODE_AVAILABLE 11
#define PF_NX_ENABLED 12
#define PF_SSE3_INSTRUCTIONS_AVAILABLE 13
#define PF_COMPARE_EXCHANGE128 14
#define PF_COMPARE64_EXCHANGE128 15
#define PF_CHANNELS_ENABLED 16
#define PF_XSAVE_ENABLED 17
#define PF_ARM_VFP_32_REGISTERS_AVAILABLE 18
#define PF_ARM_NEON_INSTRUCTIONS_AVAILABLE 19
#define PF_SECOND_LEVEL_ADDRESS_TRANSLATION 20
#define PF_VIRT_FIRMWARE_ENABLED 21
#define PF_RDWRFSGSBASE_AVAILABLE 22
#define PF_FASTFAIL_AVAILABLE 23
#define PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE 24
#define PF_ARM_64BIT_LOADSTORE_ATOMIC 25
#define PF_ARM_EXTERNAL_CACHE_AVAILABLE 26
#define PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE 27
typedef struct _SYSTEM_INFO typedef struct _SYSTEM_INFO
{ {
union union
@ -243,7 +214,91 @@ WINPR_API VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime);
WINPR_API DWORD GetTickCount(void); WINPR_API DWORD GetTickCount(void);
WINPR_API BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature);
#define PF_FLOATING_POINT_PRECISION_ERRATA 0
#define PF_FLOATING_POINT_EMULATED 1
#define PF_COMPARE_EXCHANGE_DOUBLE 2
#define PF_MMX_INSTRUCTIONS_AVAILABLE 3
#define PF_PPC_MOVEMEM_64BIT_OK 4
#define PF_XMMI_INSTRUCTIONS_AVAILABLE 6 //sse
#define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7
#define PF_RDTSC_INSTRUCTION_AVAILABLE 8
#define PF_PAE_ENABLED 9
#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10 //sse2
#define PF_SSE_DAZ_MODE_AVAILABLE 11
#define PF_NX_ENABLED 12
#define PF_SSE3_INSTRUCTIONS_AVAILABLE 13
#define PF_COMPARE_EXCHANGE128 14
#define PF_COMPARE64_EXCHANGE128 15
#define PF_CHANNELS_ENABLED 16
#define PF_XSAVE_ENABLED 17
#define PF_ARM_VFP_32_REGISTERS_AVAILABLE 18
#define PF_ARM_NEON_INSTRUCTIONS_AVAILABLE 19
#define PF_SECOND_LEVEL_ADDRESS_TRANSLATION 20
#define PF_VIRT_FIRMWARE_ENABLED 21
#define PF_RDWRFSGSBASE_AVAILABLE 22
#define PF_FASTFAIL_AVAILABLE 23
#define PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE 24
#define PF_ARM_64BIT_LOADSTORE_ATOMIC 25
#define PF_ARM_EXTERNAL_CACHE_AVAILABLE 26
#define PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE 27
#define PF_ARM_V4 0x80000001
#define PF_ARM_V5 0x80000002
#define PF_ARM_V6 0x80000003
#define PF_ARM_V7 0x80000004
#define PF_ARM_THUMB 0x80000005
#define PF_ARM_JAZELLE 0x80000006
#define PF_ARM_DSP 0x80000007
#define PF_ARM_MOVE_CP 0x80000008
#define PF_ARM_VFP10 0x80000009
#define PF_ARM_MPU 0x8000000A
#define PF_ARM_WRITE_BUFFER 0x8000000B
#define PF_ARM_MBX 0x8000000C
#define PF_ARM_L2CACHE 0x8000000D
#define PF_ARM_PHYSICALLY_TAGGED_CACHE 0x8000000E
#define PF_ARM_VFP_SINGLE_PRECISION 0x8000000F
#define PF_ARM_VFP_DOUBLE_PRECISION 0x80000010
#define PF_ARM_ITCM 0x80000011
#define PF_ARM_DTCM 0x80000012
#define PF_ARM_UNIFIED_CACHE 0x80000013
#define PF_ARM_WRITE_BACK_CACHE 0x80000014
#define PF_ARM_CACHE_CAN_BE_LOCKED_DOWN 0x80000015
#define PF_ARM_L2CACHE_MEMORY_MAPPED 0x80000016
#define PF_ARM_L2CACHE_COPROC 0x80000017
#define PF_ARM_THUMB2 0x80000018
#define PF_ARM_T2EE 0x80000019
#define PF_ARM_VFP3 0x8000001A
#define PF_ARM_NEON 0x8000001B
#define PF_ARM_UNALIGNED_ACCESS 0x8000001C
#define PF_ARM_INTEL_XSCALE 0x80010001
#define PF_ARM_INTEL_PMU 0x80010002
#define PF_ARM_INTEL_WMMX 0x80010003
#endif #endif
#endif /* WINPR_SYSINFO_H */ WINPR_API BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature);
// extended flags
#define PF_EX_3DNOW_PREFETCH 1
#define PF_EX_SSSE3 2
#define PF_EX_SSE41 3
#define PF_EX_SSE42 4
#define PF_EX_AVX 5
#define PF_EX_FMA 6
#define PF_EX_AVX_AES 7
#define PF_EX_AVX2 8
#define PF_EX_ARM_VFP1 9
#define PF_EX_ARM_VFP3D16 10
#define PF_EX_ARM_VFP4 11
#define PF_EX_ARM_IDIVA 12
#define PF_EX_ARM_IDIVT 13
// some "aliases" for the standard defines
// to be more clear
#define PF_SSE_INSTRUCTIONS_AVAILABLE PF_XMMI_INSTRUCTIONS_AVAILABLE
#define PF_SSE2_INSTRUCTIONS_AVAILABLE PF_XMMI64_INSTRUCTIONS_AVAILABLE
#endif /* WINPR_SYSINFO_H */

View File

@ -3,6 +3,7 @@
* System Information * System Information
* *
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2013 Bernhard Miklautz <bmiklautz@thinstuff.at>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -22,6 +23,13 @@
#endif #endif
#include <winpr/sysinfo.h> #include <winpr/sysinfo.h>
#include <winpr/platform.h>
#if defined(__linux__) && defined(__GNUC__)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
/** /**
* api-ms-win-core-sysinfo-l1-1-1.dll: * api-ms-win-core-sysinfo-l1-1-1.dll:
@ -109,7 +117,7 @@ DWORD GetNumberOfProcessors()
{ {
DWORD numCPUs = 1; DWORD numCPUs = 1;
/* TODO: Android and iOS */ /* TODO: iOS */
#if defined(__linux__) || defined(__sun) || defined(_AIX) #if defined(__linux__) || defined(__sun) || defined(_AIX)
numCPUs = (DWORD) sysconf(_SC_NPROCESSORS_ONLN); numCPUs = (DWORD) sysconf(_SC_NPROCESSORS_ONLN);
@ -330,5 +338,325 @@ DWORD GetTickCount(void)
return ticks; return ticks;
} }
#endif // _WIN32
/* If x86 */
#ifdef _M_IX86_AMD64
#if defined(__GNUC__) && defined(__AVX__)
#define xgetbv(_func_, _lo_, _hi_) \
__asm__ __volatile__ ("xgetbv" : "=a" (_lo_), "=d" (_hi_) : "c" (_func_))
#endif #endif
#define D_BIT_MMX (1<<23)
#define D_BIT_SSE (1<<25)
#define D_BIT_SSE2 (1<<26)
#define D_BIT_3DN (1<<30)
#define C_BIT_SSE3 (1<<0)
#define C_BIT_3DNP (1<<8)
#define C_BIT_SSSE3 (1<<9)
#define C_BIT_SSE41 (1<<19)
#define C_BIT_SSE42 (1<<20)
#define C_BIT_XGETBV (1<<27)
#define C_BIT_AVX (1<<28)
#define C_BITS_AVX (C_BIT_XGETBV|C_BIT_AVX)
#define E_BIT_XMM (1<<1)
#define E_BIT_YMM (1<<2)
#define E_BITS_AVX (E_BIT_XMM|E_BIT_YMM)
#define C_BIT_FMA (1<<11)
#define C_BIT_AVX_AES (1<<24)
static void cpuid(
unsigned info,
unsigned *eax,
unsigned *ebx,
unsigned *ecx,
unsigned *edx)
{
#ifdef __GNUC__
*eax = *ebx = *ecx = *edx = 0;
__asm volatile
(
/* The EBX (or RBX register on x86_64) is used for the PIC base address
* and must not be corrupted by our inline assembly.
*/
#ifdef _M_IX86
"mov %%ebx, %%esi;"
"cpuid;"
"xchg %%ebx, %%esi;"
#else
"mov %%rbx, %%rsi;"
"cpuid;"
"xchg %%rbx, %%rsi;"
#endif
: "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx)
: "0" (info)
);
#elif defined(_MSC_VER)
int a[4];
__cpuid(a, info);
*eax = a[0];
*ebx = a[1];
*ecx = a[2];
*edx = a[3];
#endif
}
#elif defined(_M_ARM)
#if defined(__linux__)
// HWCAP flags from linux kernel - uapi/asm/hwcap.h
#define HWCAP_SWP (1 << 0)
#define HWCAP_HALF (1 << 1)
#define HWCAP_THUMB (1 << 2)
#define HWCAP_26BIT (1 << 3) /* Play it safe */
#define HWCAP_FAST_MULT (1 << 4)
#define HWCAP_FPA (1 << 5)
#define HWCAP_VFP (1 << 6)
#define HWCAP_EDSP (1 << 7)
#define HWCAP_JAVA (1 << 8)
#define HWCAP_IWMMXT (1 << 9)
#define HWCAP_CRUNCH (1 << 10)
#define HWCAP_THUMBEE (1 << 11)
#define HWCAP_NEON (1 << 12)
#define HWCAP_VFPv3 (1 << 13)
#define HWCAP_VFPv3D16 (1 << 14) /* also set for VFPv4-D16 */
#define HWCAP_TLS (1 << 15)
#define HWCAP_VFPv4 (1 << 16)
#define HWCAP_IDIVA (1 << 17)
#define HWCAP_IDIVT (1 << 18)
#define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */
#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
// From linux kernel uapi/linux/auxvec.h
#define AT_HWCAP 16
static unsigned GetARMCPUCaps(void){
unsigned caps = 0;
int fd = open ("/proc/self/auxv", O_RDONLY);
if (fd == -1)
return 0;
static struct
{
unsigned a_type; /* Entry type */
unsigned a_val; /* Integer value */
} auxvec;
while (1){
int num;
num = read(fd, (char *)&auxvec, sizeof(auxvec));
if (num < 1 || (auxvec.a_type == 0 && auxvec.a_val == 0))
break;
if (auxvec.a_type == AT_HWCAP)
{
caps = auxvec.a_val;
}
}
close(fd);
return caps;
}
#endif // defined(__linux__)
#endif // _M_IX86_AMD64
#ifndef _WIN32
BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature)
{
BOOL ret = FALSE;
#ifdef _M_ARM
#ifdef __linux__
unsigned caps;
caps = GetARMCPUCaps();
switch (ProcessorFeature)
{
case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
case PF_ARM_NEON:
if (caps & HWCAP_NEON)
ret = TRUE;
break;
case PF_ARM_THUMB:
if (caps & HWCAP_THUMB)
ret = TRUE;
case PF_ARM_VFP_32_REGISTERS_AVAILABLE:
if (caps & HWCAP_VFPD32)
ret = TRUE;
case PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE:
if ((caps & HWCAP_IDIVA) || (caps & HWCAP_IDIVT))
ret = TRUE;
case PF_ARM_VFP3:
if (caps & HWCAP_VFPv3)
ret = TRUE;
break;
case PF_ARM_JAZELLE:
if (caps & HWCAP_JAVA)
ret = TRUE;
break;
case PF_ARM_DSP:
if (caps & HWCAP_EDSP)
ret = TRUE;
break;
case PF_ARM_MPU:
if (caps & HWCAP_EDSP)
ret = TRUE;
break;
case PF_ARM_THUMB2:
if ((caps & HWCAP_IDIVT) || (caps & HWCAP_VFPv4))
ret = TRUE;
break;
case PF_ARM_T2EE:
if (caps & HWCAP_THUMBEE)
ret = TRUE;
break;
case PF_ARM_INTEL_WMMX:
if (caps & HWCAP_IWMMXT)
ret = TRUE;
break;
default:
break;
}
#elif defined(__APPLE__) // __linux__
switch (ProcessorFeature)
{
case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
case PF_ARM_NEON:
ret = TRUE;
break;
}
#endif // __linux__
#elif defined(_M_IX86_AMD64)
#ifdef __GNUC__
unsigned a, b, c, d;
cpuid(1, &a, &b, &c, &d);
switch (ProcessorFeature)
{
case PF_MMX_INSTRUCTIONS_AVAILABLE:
if (d & D_BIT_MMX)
ret = TRUE;
break;
case PF_XMMI_INSTRUCTIONS_AVAILABLE:
if (d & D_BIT_SSE)
ret = TRUE;
break;
case PF_XMMI64_INSTRUCTIONS_AVAILABLE:
if (d & D_BIT_SSE2)
ret = TRUE;
break;
case PF_3DNOW_INSTRUCTIONS_AVAILABLE:
if (d & D_BIT_3DN)
ret = TRUE;
break;
case PF_SSE3_INSTRUCTIONS_AVAILABLE:
if (c & C_BIT_SSE3)
ret = TRUE;
break;
default:
break;
}
#endif // __GNUC__
#endif
return ret;
}
#endif //_WIN32
BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature)
{
BOOL ret = FALSE;
#ifdef _M_ARM
#ifdef __linux__
unsigned caps;
caps = GetARMCPUCaps();
switch (ProcessorFeature)
{
case PF_EX_ARM_VFP1:
if (caps & HWCAP_VFP)
ret = TRUE;
break;
case PF_EX_ARM_VFP3D16:
if (caps & HWCAP_VFPv3D16)
ret = TRUE;
break;
case PF_EX_ARM_VFP4:
if (caps & HWCAP_VFPv4)
ret = TRUE;
break;
case PF_EX_ARM_IDIVA:
if (caps & HWCAP_IDIVA)
ret = TRUE;
break;
case PF_EX_ARM_IDIVT:
if (caps & HWCAP_IDIVT)
ret = TRUE;
break;
}
#endif // __linux__
#elif defined(_M_IX86_AMD64)
unsigned a, b, c, d;
cpuid(1, &a, &b, &c, &d);
switch (ProcessorFeature)
{
case PF_EX_3DNOW_PREFETCH:
if (c & C_BIT_3DNP)
ret = TRUE;
break;
case PF_EX_SSSE3:
if (c & C_BIT_SSSE3)
ret = TRUE;
break;
case PF_EX_SSE41:
if (c & C_BIT_SSE41)
ret = TRUE;
break;
case PF_EX_SSE42:
if (c & C_BIT_SSE42)
ret = TRUE;
break;
#if defined(__GNUC__) && defined(__AVX__)
case PF_EX_AVX:
case PF_EX_FMA:
case PF_EX_AVX_AES:
{
if ((c & C_BITS_AVX) != C_BITS_AVX)
ret = FALSE;
int e, f;
xgetbv(0, e, f);
if ((e & E_BITS_AVX) == E_BITS_AVX)
{
switch (ProcessorFeature)
{
case: PF_EX_AVX:
ret = TRUE;
break;
case: PF_EX_FMA:
if (c & C_BIT_FMA)
ret = TRUE;
break;
case: PF_EX_AVX_AES:
if (c & C_BIT_AVX_AES)
ret = TRUE;
break;
{
ret = TRUE;
break;
}
}
}
break;
#endif //__AVX__
default:
break;
}
#endif
return ret;
}

View File

@ -5,7 +5,9 @@ set(MODULE_PREFIX "TEST_SYSINFO")
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
set(${MODULE_PREFIX}_TESTS set(${MODULE_PREFIX}_TESTS
TestGetNativeSystemInfo.c) TestGetNativeSystemInfo.c
TestCPUFeatures.c
)
create_test_sourcelist(${MODULE_PREFIX}_SRCS create_test_sourcelist(${MODULE_PREFIX}_SRCS
${${MODULE_PREFIX}_DRIVER} ${${MODULE_PREFIX}_DRIVER}

View File

@ -0,0 +1,45 @@
#include <winpr/crt.h>
#include <winpr/sysinfo.h>
#include <winpr/platform.h>
int TestCPUFeatures(int argc, char* argv[])
{
printf("Base CPU Flags:\n");
#ifdef _M_IX86_AMD64
printf("\tPF_MMX_INSTRUCTIONS_AVAILABLE: %s\n", IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE) ? "yes" : "no");
printf("\tPF_XMMI_INSTRUCTIONS_AVAILABLE: %s\n", IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE) ? "yes" : "no");
printf("\tPF_XMMI64_INSTRUCTIONS_AVAILABLE: %s\n", IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE) ? "yes" : "no");
printf("\tPF_3DNOW_INSTRUCTIONS_AVAILABLE: %s\n", IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE) ? "yes" : "no");
printf("\tPF_SSE3_INSTRUCTIONS_AVAILABLE: %s\n", IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE) ? "yes" : "no");
printf("\n");
printf("Extended CPU Flags (not found in windows API):\n");
printf("\tPF_EX_3DNOW_PREFETCH: %s\n", IsProcessorFeaturePresentEx(PF_EX_3DNOW_PREFETCH) ? "yes" : "no");
printf("\tPF_EX_SSSE3: %s\n", IsProcessorFeaturePresentEx(PF_EX_SSSE3) ? "yes" : "no");
printf("\tPF_EX_SSE41: %s\n", IsProcessorFeaturePresentEx(PF_EX_SSE41) ? "yes" : "no");
printf("\tPF_EX_SSE42: %s\n", IsProcessorFeaturePresentEx(PF_EX_SSE42) ? "yes" : "no");
printf("\tPF_EX_AVX: %s\n", IsProcessorFeaturePresentEx(PF_EX_AVX) ? "yes" : "no");
printf("\tPF_EX_FMA: %s\n", IsProcessorFeaturePresentEx(PF_EX_FMA) ? "yes" : "no");
printf("\tPF_EX_AVX_AES: %s\n", IsProcessorFeaturePresentEx(PF_EX_AVX_AES) ? "yes" : "no");
#elif defined(_M_ARM)
printf("\tPF_ARM_NEON_INSTRUCTIONS_AVAILABLE: %s\n", IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) ? "yes" : "no");
printf("\tPF_ARM_THUMB: %s\n", IsProcessorFeaturePresent(PF_ARM_THUMB) ? "yes" : "no");
printf("\tPF_ARM_VFP_32_REGISTERS_AVAILABLE: %s\n", IsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE) ? "yes" : "no");
printf("\tPF_ARM_DIVIDE_INSTRUCTION_AVAILABLE: %s\n", IsProcessorFeaturePresent(PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE) ? "yes" : "no");
printf("\tPF_ARM_VFP3: %s\n", IsProcessorFeaturePresent(PF_ARM_VFP3) ? "yes" : "no");
printf("\tPF_ARM_THUMB: %s\n", IsProcessorFeaturePresent(PF_ARM_THUMB) ? "yes" : "no");
printf("\tPF_ARM_JAZELLE: %s\n", IsProcessorFeaturePresent(PF_ARM_JAZELLE) ? "yes" : "no");
printf("\tPF_ARM_DSP: %s\n", IsProcessorFeaturePresent(PF_ARM_DSP) ? "yes" : "no");
printf("\tPF_ARM_THUMB2: %s\n", IsProcessorFeaturePresent(PF_ARM_THUMB2) ? "yes" : "no");
printf("\tPF_ARM_T2EE: %s\n", IsProcessorFeaturePresent(PF_ARM_T2EE) ? "yes" : "no");
printf("\tPF_ARM_INTEL_WMMX: %s\n", IsProcessorFeaturePresent(PF_ARM_INTEL_WMMX) ? "yes" : "no");
printf("Extended CPU Flags (not found in windows API):\n");
printf("\tPF_EX_ARM_VFP1: %s\n", IsProcessorFeaturePresentEx(PF_EX_ARM_VFP1) ? "yes" : "no");
printf("\tPF_EX_ARM_VFP3D16: %s\n", IsProcessorFeaturePresentEx(PF_EX_ARM_VFP3D16) ? "yes" : "no");
printf("\tPF_EX_ARM_VFP4: %s\n", IsProcessorFeaturePresentEx(PF_EX_ARM_VFP4) ? "yes" : "no");
printf("\tPF_EX_ARM_IDIVA: %s\n", IsProcessorFeaturePresentEx(PF_EX_ARM_IDIVA) ? "yes" : "no");
printf("\tPF_EX_ARM_IDIVT: %s\n", IsProcessorFeaturePresentEx(PF_EX_ARM_IDIVT) ? "yes" : "no");
#endif
printf("\n");
return 0;
}