Merge pull request #3717 from akallabeth/prim_fixes

Fixed primitives.
This commit is contained in:
Norbert Federa 2017-02-01 11:11:27 +01:00 committed by GitHub
commit 6001cb710d
20 changed files with 2389 additions and 344 deletions

View File

@ -846,8 +846,8 @@ static INLINE int progressive_decompress_tile_first(PROGRESSIVE_CONTEXT* progres
tile->crLen,
pSrcDst[2], pCurrent[2], pSign[2], diff); /* Cr */
prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2,
tile->data, tile->format,
tile->stride, &roi_64x64);
tile->data, tile->stride, tile->format,
&roi_64x64);
BufferPool_Return(progressive->bufferPool, pBuffer);
return 1;
}
@ -1261,8 +1261,8 @@ static INLINE int progressive_decompress_tile_upgrade(PROGRESSIVE_CONTEXT* progr
return -1;
prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pSrcDst, 64 * 2,
tile->data, tile->format,
tile->stride, &roi_64x64);
tile->data, tile->stride, tile->format,
&roi_64x64);
BufferPool_Return(progressive->bufferPool, pBuffer);
return 1;
}

View File

@ -91,8 +91,6 @@ static void rfx_profiler_create(RFX_CONTEXT* context)
"rfx_quantization_decode");
PROFILER_CREATE(context->priv->prof_rfx_dwt_2d_decode, "rfx_dwt_2d_decode");
PROFILER_CREATE(context->priv->prof_rfx_ycbcr_to_rgb, "prims->yCbCrToRGB");
PROFILER_CREATE(context->priv->prof_rfx_decode_format_rgb,
"rfx_decode_format_rgb");
PROFILER_CREATE(context->priv->prof_rfx_encode_rgb, "rfx_encode_rgb");
PROFILER_CREATE(context->priv->prof_rfx_encode_component,
"rfx_encode_component");
@ -116,7 +114,6 @@ static void rfx_profiler_free(RFX_CONTEXT* context)
PROFILER_FREE(context->priv->prof_rfx_quantization_decode);
PROFILER_FREE(context->priv->prof_rfx_dwt_2d_decode);
PROFILER_FREE(context->priv->prof_rfx_ycbcr_to_rgb);
PROFILER_FREE(context->priv->prof_rfx_decode_format_rgb);
PROFILER_FREE(context->priv->prof_rfx_encode_rgb);
PROFILER_FREE(context->priv->prof_rfx_encode_component);
PROFILER_FREE(context->priv->prof_rfx_rlgr_encode);
@ -137,7 +134,6 @@ static void rfx_profiler_print(RFX_CONTEXT* context)
PROFILER_PRINT(context->priv->prof_rfx_quantization_decode);
PROFILER_PRINT(context->priv->prof_rfx_dwt_2d_decode);
PROFILER_PRINT(context->priv->prof_rfx_ycbcr_to_rgb);
PROFILER_PRINT(context->priv->prof_rfx_decode_format_rgb);
PROFILER_PRINT(context->priv->prof_rfx_encode_rgb);
PROFILER_PRINT(context->priv->prof_rfx_encode_component);
PROFILER_PRINT(context->priv->prof_rfx_rlgr_encode);
@ -708,7 +704,8 @@ static BOOL rfx_process_message_region(RFX_CONTEXT* context,
Stream_Read_UINT16(s, rect->y); /* y (2 bytes) */
Stream_Read_UINT16(s, rect->width); /* width (2 bytes) */
Stream_Read_UINT16(s, rect->height); /* height (2 bytes) */
WLog_Print(context->priv->log, WLOG_DEBUG, "rect %d (x,y=%"PRIu16",%"PRIu16" w,h=%"PRIu16" %"PRIu16").", i,
WLog_Print(context->priv->log, WLOG_DEBUG,
"rect %d (x,y=%"PRIu16",%"PRIu16" w,h=%"PRIu16" %"PRIu16").", i,
rect->x, rect->y,
rect->width, rect->height);
}

View File

@ -37,26 +37,6 @@
#include "rfx_decode.h"
/* stride is bytes between rows in the output buffer. */
static void rfx_decode_format_rgb(const INT16* r_buf, const INT16* g_buf,
const INT16* b_buf, UINT32 pixel_format,
BYTE* dst_buf, UINT32 stride)
{
primitives_t* prims = primitives_get();
const INT16* r = r_buf;
const INT16* g = g_buf;
const INT16* b = b_buf;
const INT16* pSrc[3];
static const prim_size_t roi_64x64 = { 64, 64 };
BYTE* dst = dst_buf;
pSrc[0] = r;
pSrc[1] = g;
pSrc[2] = b;
prims->RGBToRGB_16s8u_P3AC4R(
(const INT16**) pSrc, 64 * sizeof(INT16),
dst, stride, pixel_format, &roi_64x64);
}
static void rfx_decode_component(RFX_CONTEXT* context,
const UINT32* quantization_values,
const BYTE* data, int size, INT16* buffer)
@ -86,6 +66,7 @@ static void rfx_decode_component(RFX_CONTEXT* context,
BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer,
int stride)
{
BOOL rc = TRUE;
BYTE* pBuffer;
INT16* pSrcDst[3];
UINT32* y_quants, *cb_quants, *cr_quants;
@ -109,14 +90,13 @@ BOOL rfx_decode_rgb(RFX_CONTEXT* context, RFX_TILE* tile, BYTE* rgb_buffer,
rfx_decode_component(context, cr_quants, tile->CrData, tile->CrLen,
pSrcDst[2]); /* CrData */
PROFILER_ENTER(context->priv->prof_rfx_ycbcr_to_rgb);
prims->yCbCrToRGB_16s16s_P3P3((const INT16**) pSrcDst, 64 * sizeof(INT16),
pSrcDst, 64 * sizeof(INT16), &roi_64x64);
if (prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**)pSrcDst, 64 * sizeof(INT16),
rgb_buffer, stride, context->pixel_format, &roi_64x64) != PRIMITIVES_SUCCESS)
rc = FALSE;
PROFILER_EXIT(context->priv->prof_rfx_ycbcr_to_rgb);
PROFILER_ENTER(context->priv->prof_rfx_decode_format_rgb);
rfx_decode_format_rgb(pSrcDst[0], pSrcDst[1], pSrcDst[2],
context->pixel_format, rgb_buffer, stride);
PROFILER_EXIT(context->priv->prof_rfx_decode_format_rgb);
PROFILER_EXIT(context->priv->prof_rfx_decode_rgb);
BufferPool_Return(context->priv->BufferPool, pBuffer);
return TRUE;
return rc;
}

View File

@ -17,8 +17,8 @@
* limitations under the License.
*/
#ifndef __RFX_TYPES_H
#define __RFX_TYPES_H
#ifndef CODEC_RFX_TYPES_H
#define CODEC_RFX_TYPES_H
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -66,7 +66,6 @@ struct _RFX_CONTEXT_PRIV
PROFILER_DEFINE(prof_rfx_quantization_decode);
PROFILER_DEFINE(prof_rfx_dwt_2d_decode);
PROFILER_DEFINE(prof_rfx_ycbcr_to_rgb);
PROFILER_DEFINE(prof_rfx_decode_format_rgb);
PROFILER_DEFINE(prof_rfx_encode_rgb);
PROFILER_DEFINE(prof_rfx_encode_component);

View File

@ -90,8 +90,10 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_invert(
status = generic->YCoCgToRGB_8u_AC4R(
sptr, srcStep, dptr, DstFormat, dstStep,
startup, 1, shift, withAlpha);
if (status != PRIMITIVES_SUCCESS)
return status;
sptr += startup * sizeof(UINT32);
dptr += startup * sizeof(UINT32);
w -= startup;
@ -203,6 +205,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_invert(
status = generic->YCoCgToRGB_8u_AC4R(
sptr, srcStep, dptr, DstFormat, dstStep,
w, 1, shift, withAlpha);
if (status != PRIMITIVES_SUCCESS)
return status;
@ -269,6 +272,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_no_invert(
status = generic->YCoCgToRGB_8u_AC4R(
sptr, srcStep, dptr, DstFormat,
dstStep, startup, 1, shift, withAlpha);
if (status != PRIMITIVES_SUCCESS)
return status;
@ -387,6 +391,7 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R_no_invert(
status = generic->YCoCgToRGB_8u_AC4R(
sptr, srcStep, dptr, DstFormat, dstStep,
w, 1, shift, withAlpha);
if (status != PRIMITIVES_SUCCESS)
return status;
@ -411,24 +416,23 @@ static pstatus_t ssse3_YCoCgRToRGB_8u_AC4R(
UINT8 shift,
BOOL withAlpha)
{
// TODO: Need to implement proper color conversion!!!
return generic->YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, DstFormat,
dstStep, width, height, shift, withAlpha);
switch (DstFormat)
{
case PIXEL_FORMAT_BGRX32:
case PIXEL_FORMAT_BGRA32:
return ssse3_YCoCgRToRGB_8u_AC4R_invert(
pSrc, srcStep, pDst, DstFormat, dstStep,
width, height, shift, withAlpha);
case PIXEL_FORMAT_RGBX32:
case PIXEL_FORMAT_RGBA32:
return ssse3_YCoCgRToRGB_8u_AC4R_no_invert(
pSrc, srcStep, pDst, DstFormat, dstStep,
width, height, shift, withAlpha);
case PIXEL_FORMAT_RGBX32:
case PIXEL_FORMAT_RGBA32:
return ssse3_YCoCgRToRGB_8u_AC4R_invert(
pSrc, srcStep, pDst, DstFormat, dstStep,
width, height, shift, withAlpha);
default:
return -1;
return generic->YCoCgToRGB_8u_AC4R(pSrc, srcStep, pDst, DstFormat,
dstStep, width, height, shift, withAlpha);
}
}
#endif /* WITH_SSE2 */

View File

@ -25,7 +25,7 @@ static primitives_t* generic = NULL;
#include <emmintrin.h>
#include <tmmintrin.h>
static pstatus_t ssse3_YUV420ToRGB_8u_P3AC4R(
static pstatus_t ssse3_YUV420ToRGB_8u_P3AC4R_BGRX(
const BYTE** pSrc, const UINT32* srcStep,
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat,
const prim_size_t* roi)
@ -35,9 +35,6 @@ static pstatus_t ssse3_YUV420ToRGB_8u_P3AC4R(
UINT32 i, nWidth, nHeight, VaddDst, VaddY, VaddU, VaddV;
__m128i r0, r1, r2, r3, r4, r5, r6, r7;
__m128i* buffer;
// TODO: Need to implement proper color conversion!!!!!
return generic->YUV420ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep,
DstFormat, roi);
/* last_line: if the last (U,V doubled) line should be skipped, set to 10B
* last_column: if it's the last column in a line, set to 10B (for handling line-endings not multiple by four) */
buffer = _aligned_malloc(4 * 16, 16);
@ -324,6 +321,21 @@ static pstatus_t ssse3_YUV420ToRGB_8u_P3AC4R(
_aligned_free(buffer);
return PRIMITIVES_SUCCESS;
}
static pstatus_t ssse3_YUV420ToRGB_8u_P3AC4R(const BYTE** pSrc, const UINT32* srcStep,
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat,
const prim_size_t* roi)
{
switch (DstFormat)
{
case PIXEL_FORMAT_BGRX32:
case PIXEL_FORMAT_BGRA32:
return ssse3_YUV420ToRGB_8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
default:
return generic->YUV420ToRGB_8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
}
}
#endif
void primitives_init_YUV_opt(primitives_t* prims)

View File

@ -34,7 +34,7 @@
/* ------------------------------------------------------------------------- */
static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_BGRX(
const INT16* pSrc[3], UINT32 srcStep,
BYTE* pDst, UINT32 DstFormat, UINT32 dstStep,
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat,
const prim_size_t* roi)
{
UINT32 x, y;
@ -51,23 +51,19 @@ static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_BGRX(
for (x = 0; x < roi->width; x++)
{
INT16 R, G, B;
const INT64 divisor = 20;
const INT64 Y = (pY[0] + 4096);
const INT64 Cb = (pCb[0]);
const INT64 Cr = (pCr[0]);
const INT64 CrR = Cr * (INT64)(1.402525f * (1 << divisor));
const INT64 CrG = Cr * (INT64)(0.714401f * (1 << divisor));
const INT64 CbG = Cb * (INT64)(0.343730f * (1 << divisor));
const INT64 CbB = Cb * (INT64)(1.769905f * (1 << divisor));
const INT64 Ytmp = (Y + 16) << divisor;
R = ((INT16)((CrR + Ytmp) >> divisor) >> 5);
G = ((INT16)((Ytmp - CbG - CrG) >> divisor) >> 5);
B = ((INT16)((CbB + Ytmp) >> divisor) >> 5);
const INT32 divisor = 16;
const INT32 Y = ((*pY++) + 4096) << divisor;
const INT32 Cb = (*pCb++);
const INT32 Cr = (*pCr++);
const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor));
const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor));
const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor));
const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor));
R = ((INT16)((CrR + Y) >> divisor) >> 5);
G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5);
B = ((INT16)((CbB + Y) >> divisor) >> 5);
pRGB = writePixelBGRX(pRGB, formatSize, DstFormat, CLIP(R), CLIP(G),
CLIP(B), 0xFF);
pY++;
pCb++;
pCr++;
}
pY += srcPad;
@ -81,7 +77,7 @@ static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_BGRX(
static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_general(
const INT16* pSrc[3], UINT32 srcStep,
BYTE* pDst, UINT32 DstFormat, UINT32 dstStep,
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat,
const prim_size_t* roi)
{
UINT32 x, y;
@ -99,23 +95,19 @@ static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_general(
for (x = 0; x < roi->width; x++)
{
INT16 R, G, B;
const INT64 divisor = 20;
const INT64 Y = (pY[0] + 4096);
const INT64 Cb = (pCb[0]);
const INT64 Cr = (pCr[0]);
const INT64 CrR = Cr * (INT64)(1.402525f * (1 << divisor));
const INT64 CrG = Cr * (INT64)(0.714401f * (1 << divisor));
const INT64 CbG = Cb * (INT64)(0.343730f * (1 << divisor));
const INT64 CbB = Cb * (INT64)(1.769905f * (1 << divisor));
const INT64 Ytmp = (Y + 16) << divisor;
R = ((INT16)((CrR + Ytmp) >> divisor) >> 5);
G = ((INT16)((Ytmp - CbG - CrG) >> divisor) >> 5);
B = ((INT16)((CbB + Ytmp) >> divisor) >> 5);
const INT32 divisor = 16;
const INT32 Y = ((*pY++) + 4096) << divisor;
const INT32 Cb = (*pCb++);
const INT32 Cr = (*pCr++);
const INT32 CrR = Cr * (INT32)(1.402525f * (1 << divisor));
const INT32 CrG = Cr * (INT32)(0.714401f * (1 << divisor));
const INT32 CbG = Cb * (INT32)(0.343730f * (1 << divisor));
const INT32 CbB = Cb * (INT32)(1.769905f * (1 << divisor));
R = ((INT16)((CrR + Y) >> divisor) >> 5);
G = ((INT16)((Y - CbG - CrG) >> divisor) >> 5);
B = ((INT16)((CbB + Y) >> divisor) >> 5);
pRGB = (*writePixel)(pRGB, formatSize, DstFormat, CLIP(R), CLIP(G),
CLIP(B), 0xFF);
pY++;
pCb++;
pCr++;
}
pY += srcPad;
@ -129,16 +121,17 @@ static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R_general(
static pstatus_t general_yCbCrToRGB_16s8u_P3AC4R(
const INT16* pSrc[3], UINT32 srcStep,
BYTE* pDst, UINT32 DstFormat, UINT32 dstStep,
BYTE* pDst, UINT32 dstStep, UINT32 DstFormat,
const prim_size_t* roi)
{
switch (DstFormat)
{
case PIXEL_FORMAT_BGRA32:
case PIXEL_FORMAT_BGRX32:
return general_yCbCrToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, DstFormat, dstStep, roi);
return general_yCbCrToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
default:
return general_yCbCrToRGB_16s8u_P3AC4R_general(pSrc, srcStep, pDst, DstFormat, dstStep, roi);
return general_yCbCrToRGB_16s8u_P3AC4R_general(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
}
}

View File

@ -356,7 +356,7 @@ static pstatus_t sse2_RGBToYCbCr_16s16s_P3P3(
#define XMM_ALL_ONES \
_mm_set1_epi32(0xFFFFFFFFU)
pstatus_t sse2_RGBToRGB_16s8u_P3AC4R(
static pstatus_t sse2_RGBToRGB_16s8u_P3AC4R_BGRX(
const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */
UINT32 srcStep, /* bytes between rows in source data */
BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */
@ -388,9 +388,6 @@ pstatus_t sse2_RGBToRGB_16s8u_P3AC4R(
dstStep, DstFormat, roi);
}
// TODO: Need to update SSE code to allow color conversion!!!
return generic->RGBToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst,
dstStep, DstFormat, roi);
out = (BYTE*) pDst;
srcbump = (srcStep - (roi->width * sizeof(UINT16))) / sizeof(UINT16);
dstbump = (dstStep - (roi->width * sizeof(UINT32)));
@ -453,15 +450,31 @@ pstatus_t sse2_RGBToRGB_16s8u_P3AC4R(
return PRIMITIVES_SUCCESS;
}
static pstatus_t sse2_RGBToRGB_16s8u_P3AC4R(
const INT16* const pSrc[3], /* 16-bit R,G, and B arrays */
UINT32 srcStep, /* bytes between rows in source data */
BYTE* pDst, /* 32-bit interleaved ARGB (ABGR?) data */
UINT32 dstStep, /* bytes between rows in dest data */
UINT32 DstFormat,
const prim_size_t* roi)
{
switch (DstFormat)
{
case PIXEL_FORMAT_BGRA32:
case PIXEL_FORMAT_BGRX32:
return sse2_RGBToRGB_16s8u_P3AC4R_BGRX(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
default:
return generic->RGBToRGB_16s8u_P3AC4R(pSrc, srcStep, pDst, dstStep, DstFormat, roi);
}
}
#endif /* WITH_SSE2 */
/*---------------------------------------------------------------------------*/
#ifdef WITH_NEON
static pstatus_t neon_yCbCrToRGB_16s16s_P3P3(
const INT16* pSrc[3],
int srcStep,
INT16* pDst[3],
int dstStep,
const INT16* pSrc[3], INT32 srcStep,
INT16* pDst[3], INT32 dstStep,
const prim_size_t* roi) /* region of interest */
{
/* TODO: If necessary, check alignments and call the general version. */
@ -545,6 +558,7 @@ static pstatus_t neon_yCbCrToRGB_16s16s_P3P3(
return PRIMITIVES_SUCCESS;
}
#endif /* WITH_NEON */

View File

@ -2299,8 +2299,8 @@ int TestPrimitivesYCbCr(int argc, char* argv[])
if (1)
{
status = prims->yCbCrToRGB_16s8u_P3AC4R((const INT16**) pYCbCr, 64 * 2,
actual, PIXEL_FORMAT_BGRA32,
64 * 4, &roi_64x64);
actual, 64 * 4, PIXEL_FORMAT_BGRA32,
&roi_64x64);
}
else
{

View File

@ -1,13 +1,14 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "prim_test.h"
#include <winpr/wlog.h>
#include <winpr/crypto.h>
#include <freerdp/primitives.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <freerdp/utils/profiler.h>
#define TAG __FILE__
@ -31,6 +32,52 @@ static BOOL similar(const BYTE* src, const BYTE* dst, size_t size)
return TRUE;
}
static BOOL similarRGB(const BYTE* src, const BYTE* dst, size_t size, UINT32 format)
{
size_t x;
const UINT32 bpp = GetBytesPerPixel(format);
const BOOL alpha = ColorHasAlpha(format);
for (x = 0; x < size; x++)
{
UINT32 sColor, dColor;
BYTE sR, sG, sB, sA;
BYTE dR, dG, dB, dA;
sColor = ReadColor(src, format);
dColor = ReadColor(dst, format);
src += bpp;
dst += bpp;
SplitColor(sColor, format, &sR, &sG, &sB, &sA, NULL);
SplitColor(sColor, format, &dR, &dG, &dB, &dA, NULL);
if ((abs(sR - dR) > 2) || (abs(sG - dG) > 2) || (abs(sB - dB) > 2))
{
fprintf(stderr, "Color value mismatch R[%02X %02X], G[%02X %02X], B[%02X %02X] at position %lu",
sR, dR, sG, dG, sA, dA, x);
return FALSE;
}
if (alpha)
{
if (abs(sA - dA) > 2)
{
fprintf(stderr, "Alpha value mismatch %02X %02X at position %lu", sA, dA, x);
return FALSE;
}
}
else
{
if (dA != 0xFF)
{
fprintf(stderr, "Invalid destination alpha value %02X at position %lu", dA, x);
return FALSE;
}
}
}
return TRUE;
}
static void get_size(UINT32* width, UINT32* height)
{
winpr_RAND((BYTE*)width, sizeof(*width));
@ -137,6 +184,8 @@ static BOOL TestPrimitiveYUVCombine(void)
UINT32 chromaStride[3];
UINT32 yuvStride[3];
size_t padding = 10000;
PROFILER_DEFINE(yuvCombine);
PROFILER_DEFINE(yuvSplit);
prim_size_t roi;
primitives_t* prims = primitives_get();
get_size(&roi.width, &roi.height);
@ -144,6 +193,8 @@ static BOOL TestPrimitiveYUVCombine(void)
aheight = roi.height + 16 - roi.height % 16;
fprintf(stderr, "Running YUVCombine on frame size %"PRIu32"x%"PRIu32" [%"PRIu32"x%"PRIu32"]\n",
roi.width, roi.height, awidth, aheight);
PROFILER_CREATE(yuvCombine, "YUV420CombineToYUV444");
PROFILER_CREATE(yuvSplit, "YUV444SplitToYUV420");
if (!prims || !prims->YUV420CombineToYUV444)
goto fail;
@ -193,10 +244,18 @@ static BOOL TestPrimitiveYUVCombine(void)
goto fail;
}
PROFILER_ENTER(yuvCombine);
if (prims->YUV420CombineToYUV444((const BYTE**)luma, lumaStride,
(const BYTE**)chroma, chromaStride,
yuv, yuvStride, &roi) != PRIMITIVES_SUCCESS)
{
PROFILER_EXIT(yuvCombine);
goto fail;
}
PROFILER_EXIT(yuvCombine);
PROFILER_PRINT(yuvCombine);
for (x = 0; x < 3; x++)
{
@ -214,9 +273,17 @@ static BOOL TestPrimitiveYUVCombine(void)
goto fail;
}
PROFILER_ENTER(yuvSplit);
if (prims->YUV444SplitToYUV420((const BYTE**)yuv, yuvStride, pmain, lumaStride,
paux, chromaStride, &roi) != PRIMITIVES_SUCCESS)
{
PROFILER_EXIT(yuvSplit);
goto fail;
}
PROFILER_EXIT(yuvSplit);
PROFILER_PRINT(yuvSplit);
for (x = 0; x < 3; x++)
{
@ -278,6 +345,8 @@ static BOOL TestPrimitiveYUVCombine(void)
rc = TRUE;
fail:
PROFILER_FREE(yuvCombine);
PROFILER_FREE(yuvSplit);
for (x = 0; x < 3; x++)
{
@ -306,12 +375,31 @@ static BOOL TestPrimitiveYUV(BOOL use444)
size_t uvsize, uvwidth;
size_t padding = 10000;
size_t stride;
const UINT32 formats[] =
{
PIXEL_FORMAT_XRGB32,
PIXEL_FORMAT_XBGR32,
PIXEL_FORMAT_ARGB32,
PIXEL_FORMAT_ABGR32,
PIXEL_FORMAT_RGBA32,
PIXEL_FORMAT_RGBX32,
PIXEL_FORMAT_BGRA32,
PIXEL_FORMAT_BGRX32
};
PROFILER_DEFINE(rgbToYUV420);
PROFILER_DEFINE(rgbToYUV444);
PROFILER_DEFINE(yuv420ToRGB);
PROFILER_DEFINE(yuv444ToRGB);
get_size(&roi.width, &roi.height);
/* Buffers need to be 16x16 aligned. */
awidth = roi.width + 16 - roi.width % 16;
aheight = roi.height + 16 - roi.height % 16;
stride = awidth * sizeof(UINT32);
size = awidth * aheight;
PROFILER_CREATE(rgbToYUV420, "RGBToYUV420");
PROFILER_CREATE(rgbToYUV444, "RGBToYUV444");
PROFILER_CREATE(yuv420ToRGB, "YUV420ToRGB");
PROFILER_CREATE(yuv444ToRGB, "YUV444ToRGB");
if (use444)
{
@ -366,17 +454,40 @@ static BOOL TestPrimitiveYUV(BOOL use444)
yuv_step[1] = uvwidth;
yuv_step[2] = uvwidth;
for (x = 0; x < sizeof(formats) / sizeof(formats[0]); x++)
{
const UINT32 DstFormat = formats[x];
if (use444)
{
if (prims->RGBToYUV444_8u_P3AC4R(rgb, PIXEL_FORMAT_BGRA32,
PROFILER_ENTER(rgbToYUV444);
if (prims->RGBToYUV444_8u_P3AC4R(rgb, DstFormat,
stride, yuv, yuv_step,
&roi) != PRIMITIVES_SUCCESS)
{
PROFILER_EXIT(rgbToYUV444);
goto fail;
}
else if (prims->RGBToYUV420_8u_P3AC4R(rgb, PIXEL_FORMAT_BGRA32,
PROFILER_EXIT(rgbToYUV444);
PROFILER_PRINT(rgbToYUV444);
}
else
{
PROFILER_ENTER(rgbToYUV420);
if (prims->RGBToYUV420_8u_P3AC4R(rgb, DstFormat,
stride, yuv, yuv_step,
&roi) != PRIMITIVES_SUCCESS)
{
PROFILER_EXIT(rgbToYUV420);
goto fail;
}
PROFILER_EXIT(rgbToYUV420);
PROFILER_PRINT(rgbToYUV420);
}
if (!check_padding(rgb, size * sizeof(UINT32), padding, "rgb"))
goto fail;
@ -388,14 +499,33 @@ static BOOL TestPrimitiveYUV(BOOL use444)
if (use444)
{
PROFILER_ENTER(yuv444ToRGB);
if (prims->YUV444ToRGB_8u_P3AC4R((const BYTE**)yuv, yuv_step, rgb_dst, stride,
PIXEL_FORMAT_BGRA32,
DstFormat,
&roi) != PRIMITIVES_SUCCESS)
{
PROFILER_EXIT(yuv444ToRGB);
goto fail;
}
else if (prims->YUV420ToRGB_8u_P3AC4R((const BYTE**)yuv, yuv_step, rgb_dst,
stride, PIXEL_FORMAT_BGRA32, &roi) != PRIMITIVES_SUCCESS)
PROFILER_EXIT(yuv444ToRGB);
PROFILER_PRINT(yuv444ToRGB);
}
else
{
PROFILER_ENTER(yuv420ToRGB);
if (prims->YUV420ToRGB_8u_P3AC4R((const BYTE**)yuv, yuv_step, rgb_dst,
stride, DstFormat, &roi) != PRIMITIVES_SUCCESS)
{
PROFILER_EXIT(yuv420ToRGB);
goto fail;
}
PROFILER_EXIT(yuv420ToRGB);
PROFILER_PRINT(yuv420ToRGB);
}
if (!check_padding(rgb_dst, size * sizeof(UINT32), padding, "rgb dst"))
goto fail;
@ -410,12 +540,17 @@ static BOOL TestPrimitiveYUV(BOOL use444)
BYTE* srgb = &rgb[y * stride];
BYTE* drgb = &rgb_dst[y * stride];
if (!similar(srgb, drgb, roi.width * sizeof(UINT32)))
if (!similarRGB(srgb, drgb, roi.width, DstFormat))
goto fail;
}
}
rc = TRUE;
fail:
PROFILER_FREE(rgbToYUV420);
PROFILER_FREE(rgbToYUV444);
PROFILER_FREE(yuv420ToRGB);
PROFILER_FREE(yuv444ToRGB);
free_padding(rgb, padding);
free_padding(rgb_dst, padding);
free_padding(yuv[0], padding);
@ -428,7 +563,6 @@ int TestPrimitivesYUV(int argc, char* argv[])
{
UINT32 x;
int rc = -1;
prim_test_setup(FALSE);
for (x = 0; x < 10; x++)

View File

@ -22,8 +22,12 @@
* Define GOOGLE_PROFILER if you want gperftools included.
*/
#ifndef __MEASURE_H_INCLUDED__
#define __MEASURE_H_INCLUDED__
#ifndef TEST_MEASURE_H_INCLUDED
#define TEST_MEASURE_H_INCLUDED
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <time.h>

View File

@ -86,6 +86,15 @@
#endif
#endif
/* MIPS64 (_M_MIPS64) */
#if defined(mips64) || defined(__mips64) || \
defined(__mips64__) || defined(__MIPS64__)
#ifndef _M_MIPS64
#define _M_MIPS64 1
#endif
#endif
/* PowerPC (_M_PPC) */
#if defined(__ppc__) || defined(__powerpc) || \

View File

@ -44,6 +44,8 @@ extern "C" {
#define PROCESSOR_ARCHITECTURE_AMD64 9
#define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
#define PROCESSOR_ARCHITECTURE_NEUTRAL 11
#define PROCESSOR_ARCHITECTURE_ARM64 12
#define PROCESSOR_ARCHITECTURE_MIPS64 13
#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF
#define PROCESSOR_INTEL_386 386
@ -189,7 +191,8 @@ WINPR_API VOID GetLocalTime(LPSYSTEMTIME lpSystemTime);
WINPR_API BOOL SetLocalTime(CONST SYSTEMTIME* lpSystemTime);
WINPR_API VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime);
WINPR_API BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement, PBOOL lpTimeAdjustmentDisabled);
WINPR_API BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement,
PBOOL lpTimeAdjustmentDisabled);
WINPR_API BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature);

View File

@ -15,6 +15,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
if(ANDROID)
add_subdirectory(cpufeatures)
endif()
winpr_module_add(sysinfo.c)
if((NOT WIN32) AND (NOT APPLE) AND (NOT ANDROID) AND (NOT OPENBSD))

View File

@ -0,0 +1,20 @@
# WinPR: Windows Portable Runtime
# libwinpr-sysinfo cmake build script
#
# Copyright 2017 Armin Novak <armin.novak@thincast.com>
# Copyright 2017 Thincast Technologies GmbH
#
# 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.
winpr_module_add(cpu-features.c cpu-features.h)

View File

@ -0,0 +1,13 @@
Copyright (C) 2016 The Android Open Source Project
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.

View File

@ -0,0 +1,4 @@
Android CPUFeatures Library
https://developer.android.com/ndk/guides/cpu-features.html
https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,328 @@
/*
* Copyright (C) 2010 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef CPU_FEATURES_H
#define CPU_FEATURES_H
#include <sys/cdefs.h>
#include <stdint.h>
__BEGIN_DECLS
/* A list of valid values returned by android_getCpuFamily().
* They describe the CPU Architecture of the current process.
*/
typedef enum
{
ANDROID_CPU_FAMILY_UNKNOWN = 0,
ANDROID_CPU_FAMILY_ARM,
ANDROID_CPU_FAMILY_X86,
ANDROID_CPU_FAMILY_MIPS,
ANDROID_CPU_FAMILY_ARM64,
ANDROID_CPU_FAMILY_X86_64,
ANDROID_CPU_FAMILY_MIPS64,
ANDROID_CPU_FAMILY_MAX /* do not remove */
} AndroidCpuFamily;
/* Return the CPU family of the current process.
*
* Note that this matches the bitness of the current process. I.e. when
* running a 32-bit binary on a 64-bit capable CPU, this will return the
* 32-bit CPU family value.
*/
extern AndroidCpuFamily android_getCpuFamily(void);
/* Return a bitmap describing a set of optional CPU features that are
* supported by the current device's CPU. The exact bit-flags returned
* depend on the value returned by android_getCpuFamily(). See the
* documentation for the ANDROID_CPU_*_FEATURE_* flags below for details.
*/
extern uint64_t android_getCpuFeatures(void);
/* The list of feature flags for ANDROID_CPU_FAMILY_ARM that can be
* recognized by the library (see note below for 64-bit ARM). Value details
* are:
*
* VFPv2:
* CPU supports the VFPv2 instruction set. Many, but not all, ARMv6 CPUs
* support these instructions. VFPv2 is a subset of VFPv3 so this will
* be set whenever VFPv3 is set too.
*
* ARMv7:
* CPU supports the ARMv7-A basic instruction set.
* This feature is mandated by the 'armeabi-v7a' ABI.
*
* VFPv3:
* CPU supports the VFPv3-D16 instruction set, providing hardware FPU
* support for single and double precision floating point registers.
* Note that only 16 FPU registers are available by default, unless
* the D32 bit is set too. This feature is also mandated by the
* 'armeabi-v7a' ABI.
*
* VFP_D32:
* CPU VFP optional extension that provides 32 FPU registers,
* instead of 16. Note that ARM mandates this feature is the 'NEON'
* feature is implemented by the CPU.
*
* NEON:
* CPU FPU supports "ARM Advanced SIMD" instructions, also known as
* NEON. Note that this mandates the VFP_D32 feature as well, per the
* ARM Architecture specification.
*
* VFP_FP16:
* Half-width floating precision VFP extension. If set, the CPU
* supports instructions to perform floating-point operations on
* 16-bit registers. This is part of the VFPv4 specification, but
* not mandated by any Android ABI.
*
* VFP_FMA:
* Fused multiply-accumulate VFP instructions extension. Also part of
* the VFPv4 specification, but not mandated by any Android ABI.
*
* NEON_FMA:
* Fused multiply-accumulate NEON instructions extension. Optional
* extension from the VFPv4 specification, but not mandated by any
* Android ABI.
*
* IDIV_ARM:
* Integer division available in ARM mode. Only available
* on recent CPUs (e.g. Cortex-A15).
*
* IDIV_THUMB2:
* Integer division available in Thumb-2 mode. Only available
* on recent CPUs (e.g. Cortex-A15).
*
* iWMMXt:
* Optional extension that adds MMX registers and operations to an
* ARM CPU. This is only available on a few XScale-based CPU designs
* sold by Marvell. Pretty rare in practice.
*
* AES:
* CPU supports AES instructions. These instructions are only
* available for 32-bit applications running on ARMv8 CPU.
*
* CRC32:
* CPU supports CRC32 instructions. These instructions are only
* available for 32-bit applications running on ARMv8 CPU.
*
* SHA2:
* CPU supports SHA2 instructions. These instructions are only
* available for 32-bit applications running on ARMv8 CPU.
*
* SHA1:
* CPU supports SHA1 instructions. These instructions are only
* available for 32-bit applications running on ARMv8 CPU.
*
* PMULL:
* CPU supports 64-bit PMULL and PMULL2 instructions. These
* instructions are only available for 32-bit applications
* running on ARMv8 CPU.
*
* If you want to tell the compiler to generate code that targets one of
* the feature set above, you should probably use one of the following
* flags (for more details, see technical note at the end of this file):
*
* -mfpu=vfp
* -mfpu=vfpv2
* These are equivalent and tell GCC to use VFPv2 instructions for
* floating-point operations. Use this if you want your code to
* run on *some* ARMv6 devices, and any ARMv7-A device supported
* by Android.
*
* Generated code requires VFPv2 feature.
*
* -mfpu=vfpv3-d16
* Tell GCC to use VFPv3 instructions (using only 16 FPU registers).
* This should be generic code that runs on any CPU that supports the
* 'armeabi-v7a' Android ABI. Note that no ARMv6 CPU supports this.
*
* Generated code requires VFPv3 feature.
*
* -mfpu=vfpv3
* Tell GCC to use VFPv3 instructions with 32 FPU registers.
* Generated code requires VFPv3|VFP_D32 features.
*
* -mfpu=neon
* Tell GCC to use VFPv3 instructions with 32 FPU registers, and
* also support NEON intrinsics (see <arm_neon.h>).
* Generated code requires VFPv3|VFP_D32|NEON features.
*
* -mfpu=vfpv4-d16
* Generated code requires VFPv3|VFP_FP16|VFP_FMA features.
*
* -mfpu=vfpv4
* Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32 features.
*
* -mfpu=neon-vfpv4
* Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32|NEON|NEON_FMA
* features.
*
* -mcpu=cortex-a7
* -mcpu=cortex-a15
* Generated code requires VFPv3|VFP_FP16|VFP_FMA|VFP_D32|
* NEON|NEON_FMA|IDIV_ARM|IDIV_THUMB2
* This flag implies -mfpu=neon-vfpv4.
*
* -mcpu=iwmmxt
* Allows the use of iWMMXt instrinsics with GCC.
*
* IMPORTANT NOTE: These flags should only be tested when
* android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, i.e. this is a
* 32-bit process.
*
* When running a 64-bit ARM process on an ARMv8 CPU,
* android_getCpuFeatures() will return a different set of bitflags
*/
enum
{
ANDROID_CPU_ARM_FEATURE_ARMv7 = (1 << 0),
ANDROID_CPU_ARM_FEATURE_VFPv3 = (1 << 1),
ANDROID_CPU_ARM_FEATURE_NEON = (1 << 2),
ANDROID_CPU_ARM_FEATURE_LDREX_STREX = (1 << 3),
ANDROID_CPU_ARM_FEATURE_VFPv2 = (1 << 4),
ANDROID_CPU_ARM_FEATURE_VFP_D32 = (1 << 5),
ANDROID_CPU_ARM_FEATURE_VFP_FP16 = (1 << 6),
ANDROID_CPU_ARM_FEATURE_VFP_FMA = (1 << 7),
ANDROID_CPU_ARM_FEATURE_NEON_FMA = (1 << 8),
ANDROID_CPU_ARM_FEATURE_IDIV_ARM = (1 << 9),
ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 = (1 << 10),
ANDROID_CPU_ARM_FEATURE_iWMMXt = (1 << 11),
ANDROID_CPU_ARM_FEATURE_AES = (1 << 12),
ANDROID_CPU_ARM_FEATURE_PMULL = (1 << 13),
ANDROID_CPU_ARM_FEATURE_SHA1 = (1 << 14),
ANDROID_CPU_ARM_FEATURE_SHA2 = (1 << 15),
ANDROID_CPU_ARM_FEATURE_CRC32 = (1 << 16),
};
/* The bit flags corresponding to the output of android_getCpuFeatures()
* when android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM64. Value details
* are:
*
* FP:
* CPU has Floating-point unit.
*
* ASIMD:
* CPU has Advanced SIMD unit.
*
* AES:
* CPU supports AES instructions.
*
* CRC32:
* CPU supports CRC32 instructions.
*
* SHA2:
* CPU supports SHA2 instructions.
*
* SHA1:
* CPU supports SHA1 instructions.
*
* PMULL:
* CPU supports 64-bit PMULL and PMULL2 instructions.
*/
enum
{
ANDROID_CPU_ARM64_FEATURE_FP = (1 << 0),
ANDROID_CPU_ARM64_FEATURE_ASIMD = (1 << 1),
ANDROID_CPU_ARM64_FEATURE_AES = (1 << 2),
ANDROID_CPU_ARM64_FEATURE_PMULL = (1 << 3),
ANDROID_CPU_ARM64_FEATURE_SHA1 = (1 << 4),
ANDROID_CPU_ARM64_FEATURE_SHA2 = (1 << 5),
ANDROID_CPU_ARM64_FEATURE_CRC32 = (1 << 6),
};
/* The bit flags corresponding to the output of android_getCpuFeatures()
* when android_getCpuFamily() returns ANDROID_CPU_FAMILY_X86 or
* ANDROID_CPU_FAMILY_X86_64.
*/
enum
{
ANDROID_CPU_X86_FEATURE_SSSE3 = (1 << 0),
ANDROID_CPU_X86_FEATURE_POPCNT = (1 << 1),
ANDROID_CPU_X86_FEATURE_MOVBE = (1 << 2),
ANDROID_CPU_X86_FEATURE_SSE4_1 = (1 << 3),
ANDROID_CPU_X86_FEATURE_SSE4_2 = (1 << 4),
ANDROID_CPU_X86_FEATURE_AES_NI = (1 << 5),
ANDROID_CPU_X86_FEATURE_AVX = (1 << 6),
ANDROID_CPU_X86_FEATURE_RDRAND = (1 << 7),
ANDROID_CPU_X86_FEATURE_AVX2 = (1 << 8),
ANDROID_CPU_X86_FEATURE_SHA_NI = (1 << 9),
};
/* The bit flags corresponding to the output of android_getCpuFeatures()
* when android_getCpuFamily() returns ANDROID_CPU_FAMILY_MIPS
* or ANDROID_CPU_FAMILY_MIPS64. Values are:
*
* R6:
* CPU executes MIPS Release 6 instructions natively, and
* supports obsoleted R1..R5 instructions only via kernel traps.
*
* MSA:
* CPU supports Mips SIMD Architecture instructions.
*/
enum
{
ANDROID_CPU_MIPS_FEATURE_R6 = (1 << 0),
ANDROID_CPU_MIPS_FEATURE_MSA = (1 << 1),
};
/* Return the number of CPU cores detected on this device. */
extern int android_getCpuCount(void);
/* The following is used to force the CPU count and features
* mask in sandboxed processes. Under 4.1 and higher, these processes
* cannot access /proc, which is the only way to get information from
* the kernel about the current hardware (at least on ARM).
*
* It _must_ be called only once, and before any android_getCpuXXX
* function, any other case will fail.
*
* This function return 1 on success, and 0 on failure.
*/
extern int android_setCpu(int cpu_count,
uint64_t cpu_features);
#ifdef __arm__
/* Retrieve the ARM 32-bit CPUID value from the kernel.
* Note that this cannot work on sandboxed processes under 4.1 and
* higher, unless you called android_setCpuArm() before.
*/
extern uint32_t android_getCpuIdArm(void);
/* An ARM-specific variant of android_setCpu() that also allows you
* to set the ARM CPUID field.
*/
extern int android_setCpuArm(int cpu_count,
uint64_t cpu_features,
uint32_t cpu_id);
#endif
__END_DECLS
#endif /* CPU_FEATURES_H */

View File

@ -25,7 +25,11 @@
#include <winpr/sysinfo.h>
#include <winpr/platform.h>
#if defined(__linux__) && defined(__GNUC__)
#if defined(ANDROID)
#include "cpufeatures/cpu-features.h"
#endif
#if defined(__linux__)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@ -72,19 +76,49 @@ defined(__OpenBSD__) || defined(__DragonFly__)
#include <sys/sysctl.h>
#endif
static DWORD GetProcessorArchitecture()
static DWORD GetProcessorArchitecture(void)
{
DWORD cpuArch = PROCESSOR_ARCHITECTURE_UNKNOWN;
#if defined(_M_AMD64)
cpuArch = PROCESSOR_ARCHITECTURE_AMD64;
#elif defined(_M_IX86)
cpuArch = PROCESSOR_ARCHITECTURE_INTEL;
#if defined(ANDROID)
AndroidCpuFamily family = android_getCpuFamily();
switch (family)
{
case ANDROID_CPU_FAMILY_ARM:
return PROCESSOR_ARCHITECTURE_ARM;
case ANDROID_CPU_FAMILY_X86:
return PROCESSOR_ARCHITECTURE_INTEL;
case ANDROID_CPU_FAMILY_MIPS:
return PROCESSOR_ARCHITECTURE_MIPS;
case ANDROID_CPU_FAMILY_ARM64:
return PROCESSOR_ARCHITECTURE_ARM64;
case ANDROID_CPU_FAMILY_X86_64:
return PROCESSOR_ARCHITECTURE_AMD64;
case ANDROID_CPU_FAMILY_MIPS64:
return PROCESSOR_ARCHITECTURE_MIPS64;
default:
return PROCESSOR_ARCHITECTURE_UNKNOWN;
}
#elif defined(_M_ARM)
cpuArch = PROCESSOR_ARCHITECTURE_ARM;
#elif defined(_M_IA64)
cpuArch = PROCESSOR_ARCHITECTURE_IA64;
#elif defined(_M_IX86)
cpuArch = PROCESSOR_ARCHITECTURE_INTEL;
#elif defined(_M_MIPS64)
/* Needs to be before __mips__ since the compiler defines both */
cpuArch = PROCESSOR_ARCHITECTURE_MIPS64;
#elif defined(_M_MIPS)
cpuArch = PROCESSOR_ARCHITECTURE_MIPS;
#elif defined(_M_ARM64)
cpuArch = PROCESSOR_ARCHITECTURE_ARM64;
#elif defined(_M_AMD64)
cpuArch = PROCESSOR_ARCHITECTURE_AMD64;
#elif defined(_M_PPC)
cpuArch = PROCESSOR_ARCHITECTURE_PPC;
#elif defined(_M_ALPHA)
@ -93,11 +127,13 @@ static DWORD GetProcessorArchitecture()
return cpuArch;
}
static DWORD GetNumberOfProcessors()
static DWORD GetNumberOfProcessors(void)
{
DWORD numCPUs = 1;
#if defined(ANDROID)
return android_getCpuCount();
/* TODO: iOS */
#if defined(__linux__) || defined(__sun) || defined(_AIX)
#elif defined(__linux__) || defined(__sun) || defined(_AIX)
numCPUs = (DWORD) sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(__MACOSX__) || \
defined(__FreeBSD__) || defined(__NetBSD__) || \
@ -130,19 +166,21 @@ static DWORD GetNumberOfProcessors()
return numCPUs;
}
static DWORD GetSystemPageSize()
static DWORD GetSystemPageSize(void)
{
DWORD dwPageSize = 0;
long sc_page_size = -1;
#if defined(_SC_PAGESIZE)
if (sc_page_size < 0)
sc_page_size = sysconf(_SC_PAGESIZE);
#endif
#endif
#if defined(_SC_PAGE_SIZE)
if (sc_page_size < 0)
sc_page_size = sysconf(_SC_PAGE_SIZE);
#endif
if (sc_page_size > 0)
@ -199,6 +237,7 @@ void GetSystemTime(LPSYSTEMTIME lpSystemTime)
BOOL SetSystemTime(CONST SYSTEMTIME* lpSystemTime)
{
/* TODO: Implement */
return FALSE;
}
@ -227,6 +266,7 @@ VOID GetLocalTime(LPSYSTEMTIME lpSystemTime)
BOOL SetLocalTime(CONST SYSTEMTIME* lpSystemTime)
{
/* TODO: Implement */
return FALSE;
}
@ -241,8 +281,10 @@ VOID GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
lpSystemTimeAsFileTime->dwHighDateTime = time64.HighPart;
}
BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement, PBOOL lpTimeAdjustmentDisabled)
BOOL GetSystemTimeAdjustment(PDWORD lpTimeAdjustment, PDWORD lpTimeIncrement,
PBOOL lpTimeAdjustmentDisabled)
{
/* TODO: Implement */
return FALSE;
}
@ -283,6 +325,7 @@ DWORD GetTickCount(void)
BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation)
{
#ifdef _UWP
/* Windows 10 Version Info */
if ((lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA)) ||
(lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA)))
@ -305,7 +348,9 @@ BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation)
return TRUE;
}
#else
/* Windows 7 SP1 Version Info */
if ((lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA)) ||
(lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOEXA)))
@ -328,8 +373,8 @@ BOOL GetVersionExA(LPOSVERSIONINFOA lpVersionInformation)
return TRUE;
}
#endif
#endif
return FALSE;
}
@ -371,7 +416,6 @@ BOOL GetComputerNameA(LPSTR lpBuffer, LPDWORD lpnSize)
CopyMemory(lpBuffer, hostname, length);
lpBuffer[length] = '\0';
*lpnSize = length;
return TRUE;
}
@ -595,10 +639,22 @@ static unsigned GetARMCPUCaps(void)
BOOL IsProcessorFeaturePresent(DWORD ProcessorFeature)
{
BOOL ret = FALSE;
#ifdef _M_ARM
#if defined(ANDROID)
const uint64_t features = android_getCpuFeatures();
switch (ProcessorFeature)
{
case PF_ARM_NEON_INSTRUCTIONS_AVAILABLE:
case PF_ARM_NEON:
return features & ANDROID_CPU_ARM_FEATURE_NEON;
default:
return FALSE;
}
#elif defined(_M_ARM)
#ifdef __linux__
unsigned caps;
caps = GetARMCPUCaps();
const unsigned caps = GetARMCPUCaps();
switch (ProcessorFeature)
{
@ -731,10 +787,8 @@ DWORD GetTickCountPrecise(void)
#ifdef _WIN32
LARGE_INTEGER freq;
LARGE_INTEGER current;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&current);
return (DWORD)(current.QuadPart * 1000LL / freq.QuadPart);
#else
return GetTickCount();
@ -793,6 +847,7 @@ BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature)
{
unsigned a81, b81, c81, d81;
cpuid(0x80000001, &a81, &b81, &c81, &d81);
if (c81 & C81_BIT_LZCNT)
ret = TRUE;
}