[codec,progressive] use preallocated workers

allocate PTP_WORK and PROGRESSIVE_TILE_PROCESS_WORK_PARAM in
PROGRESSIVE_BLOCK_REGION
This commit is contained in:
akallabeth 2024-06-04 14:32:42 +02:00
parent b17b07885a
commit 3c2702afd3
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5
2 changed files with 88 additions and 99 deletions

View File

@ -388,18 +388,18 @@ static INLINE RFX_PROGRESSIVE_TILE* progressive_tile_new(void)
tile->stride = 4 * tile->width; tile->stride = 4 * tile->width;
size_t dataLen = 1ull * tile->stride * tile->height; size_t dataLen = 1ull * tile->stride * tile->height;
tile->data = (BYTE*)winpr_aligned_calloc(dataLen, sizeof(BYTE), 16); tile->data = (BYTE*)winpr_aligned_malloc(dataLen, 16);
if (!tile->data) if (!tile->data)
goto fail; goto fail;
memset(tile->data, 0xFF, dataLen); memset(tile->data, 0xFF, dataLen);
size_t signLen = (8192 + 32) * 3; size_t signLen = (8192 + 32) * 3;
tile->sign = (BYTE*)winpr_aligned_calloc(signLen, sizeof(BYTE), 16); tile->sign = (BYTE*)winpr_aligned_malloc(signLen, 16);
if (!tile->sign) if (!tile->sign)
goto fail; goto fail;
size_t currentLen = (8192 + 32) * 3; size_t currentLen = (8192 + 32) * 3;
tile->current = (BYTE*)winpr_aligned_calloc(currentLen, sizeof(BYTE), 16); tile->current = (BYTE*)winpr_aligned_malloc(currentLen, 16);
if (!tile->current) if (!tile->current)
goto fail; goto fail;
@ -410,8 +410,8 @@ fail:
return NULL; return NULL;
} }
static BOOL progressive_allocate_tile_cache(PROGRESSIVE_SURFACE_CONTEXT* WINPR_RESTRICT surface, static INLINE BOOL
size_t min) progressive_allocate_tile_cache(PROGRESSIVE_SURFACE_CONTEXT* WINPR_RESTRICT surface, size_t min)
{ {
size_t oldIndex = 0; size_t oldIndex = 0;
@ -474,10 +474,10 @@ static PROGRESSIVE_SURFACE_CONTEXT* progressive_surface_context_new(UINT16 surfa
return surface; return surface;
} }
static BOOL progressive_surface_tile_replace(PROGRESSIVE_SURFACE_CONTEXT* WINPR_RESTRICT surface, static INLINE BOOL
progressive_surface_tile_replace(PROGRESSIVE_SURFACE_CONTEXT* WINPR_RESTRICT surface,
PROGRESSIVE_BLOCK_REGION* WINPR_RESTRICT region, PROGRESSIVE_BLOCK_REGION* WINPR_RESTRICT region,
const RFX_PROGRESSIVE_TILE* WINPR_RESTRICT tile, const RFX_PROGRESSIVE_TILE* WINPR_RESTRICT tile, BOOL upgrade)
BOOL upgrade)
{ {
RFX_PROGRESSIVE_TILE* t = NULL; RFX_PROGRESSIVE_TILE* t = NULL;
@ -1650,14 +1650,6 @@ static INLINE BOOL progressive_tile_read(PROGRESSIVE_CONTEXT* WINPR_RESTRICT pro
return progressive_surface_tile_replace(surface, region, &tile, FALSE); return progressive_surface_tile_replace(surface, region, &tile, FALSE);
} }
typedef struct
{
PROGRESSIVE_CONTEXT* progressive;
PROGRESSIVE_BLOCK_REGION* region;
const PROGRESSIVE_BLOCK_CONTEXT* context;
RFX_PROGRESSIVE_TILE* tile;
} PROGRESSIVE_TILE_PROCESS_WORK_PARAM;
static void CALLBACK progressive_process_tiles_tile_work_callback(PTP_CALLBACK_INSTANCE instance, static void CALLBACK progressive_process_tiles_tile_work_callback(PTP_CALLBACK_INSTANCE instance,
void* context, PTP_WORK work) void* context, PTP_WORK work)
{ {
@ -1698,8 +1690,6 @@ static INLINE SSIZE_T progressive_process_tiles(
UINT16 blockType = 0; UINT16 blockType = 0;
UINT32 blockLen = 0; UINT32 blockLen = 0;
UINT32 count = 0; UINT32 count = 0;
PTP_WORK* work_objects = NULL;
PROGRESSIVE_TILE_PROCESS_WORK_PARAM* params = NULL;
UINT16 close_cnt = 0; UINT16 close_cnt = 0;
WINPR_ASSERT(progressive); WINPR_ASSERT(progressive);
@ -1782,28 +1772,10 @@ static INLINE SSIZE_T progressive_process_tiles(
return -1044; return -1044;
} }
{
size_t tcount = 1;
if (progressive->rfx_context->priv->UseThreads)
tcount = region->numTiles;
work_objects = (PTP_WORK*)winpr_aligned_calloc(tcount, sizeof(PTP_WORK), 32);
if (!work_objects)
return -1;
}
params = (PROGRESSIVE_TILE_PROCESS_WORK_PARAM*)winpr_aligned_calloc(
region->numTiles, sizeof(PROGRESSIVE_TILE_PROCESS_WORK_PARAM), 32);
if (!params)
{
winpr_aligned_free(work_objects);
return -1;
}
for (UINT32 idx = 0; idx < region->numTiles; idx++) for (UINT32 idx = 0; idx < region->numTiles; idx++)
{ {
RFX_PROGRESSIVE_TILE* tile = region->tiles[idx]; RFX_PROGRESSIVE_TILE* tile = region->tiles[idx];
PROGRESSIVE_TILE_PROCESS_WORK_PARAM* param = &params[idx]; PROGRESSIVE_TILE_PROCESS_WORK_PARAM* param = &progressive->params[idx];
param->progressive = progressive; param->progressive = progressive;
param->region = region; param->region = region;
param->context = context; param->context = context;
@ -1811,9 +1783,10 @@ static INLINE SSIZE_T progressive_process_tiles(
if (progressive->rfx_context->priv->UseThreads) if (progressive->rfx_context->priv->UseThreads)
{ {
if (!(work_objects[idx] = CreateThreadpoolWork( progressive->work_objects[idx] =
progressive_process_tiles_tile_work_callback, (void*)&params[idx], CreateThreadpoolWork(progressive_process_tiles_tile_work_callback, (void*)param,
&progressive->rfx_context->priv->ThreadPoolEnv))) &progressive->rfx_context->priv->ThreadPoolEnv);
if (!progressive->work_objects[idx])
{ {
WLog_Print(progressive->log, WLOG_ERROR, WLog_Print(progressive->log, WLOG_ERROR,
"Failed to create ThreadpoolWork for tile %" PRIu32, idx); "Failed to create ThreadpoolWork for tile %" PRIu32, idx);
@ -1821,12 +1794,12 @@ static INLINE SSIZE_T progressive_process_tiles(
break; break;
} }
SubmitThreadpoolWork(work_objects[idx]); SubmitThreadpoolWork(progressive->work_objects[idx]);
close_cnt = idx + 1; close_cnt = idx + 1;
} }
else else
{ {
progressive_process_tiles_tile_work_callback(0, &params[idx], 0); progressive_process_tiles_tile_work_callback(0, param, 0);
} }
if (status < 0) if (status < 0)
@ -1841,14 +1814,12 @@ static INLINE SSIZE_T progressive_process_tiles(
{ {
for (UINT32 idx = 0; idx < close_cnt; idx++) for (UINT32 idx = 0; idx < close_cnt; idx++)
{ {
WaitForThreadpoolWorkCallbacks(work_objects[idx], FALSE); WaitForThreadpoolWorkCallbacks(progressive->work_objects[idx], FALSE);
CloseThreadpoolWork(work_objects[idx]); CloseThreadpoolWork(progressive->work_objects[idx]);
} }
} }
fail: fail:
winpr_aligned_free(work_objects);
winpr_aligned_free(params);
if (status < 0) if (status < 0)
return -1; return -1;
@ -2050,9 +2021,7 @@ static INLINE SSIZE_T progressive_wb_read_region_header(
PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive, wStream* WINPR_RESTRICT s, UINT16 blockType, PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive, wStream* WINPR_RESTRICT s, UINT16 blockType,
UINT32 blockLen, PROGRESSIVE_BLOCK_REGION* WINPR_RESTRICT region) UINT32 blockLen, PROGRESSIVE_BLOCK_REGION* WINPR_RESTRICT region)
{ {
SSIZE_T len = 0; region->usedTiles = 0;
memset(region, 0, sizeof(PROGRESSIVE_BLOCK_REGION));
if (!Stream_CheckAndLogRequiredLength(TAG, s, 12)) if (!Stream_CheckAndLogRequiredLength(TAG, s, 12))
return -1011; return -1011;
@ -2090,58 +2059,64 @@ static INLINE SSIZE_T progressive_wb_read_region_header(
return -1014; return -1014;
} }
len = Stream_GetRemainingLength(s); const SSIZE_T rc = Stream_GetRemainingLength(s);
if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, region->numRects, 8ull)) const SSIZE_T expect = region->numRects * 8ll + region->numQuant * 5ll +
region->numProgQuant * 16ll + region->tileDataSize;
SSIZE_T len = rc;
if (expect != rc)
{ {
WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion data short for region->rects"); if (len / 8LL < region->numRects)
{
WLog_Print(progressive->log, WLOG_ERROR,
"ProgressiveRegion data short for region->rects");
return -1015; return -1015;
} }
len -= region->numRects * 8ULL; len -= region->numRects * 8LL;
if (len / 5 < region->numQuant) if (len / 5LL < region->numQuant)
{ {
WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion data short for region->cQuant"); WLog_Print(progressive->log, WLOG_ERROR,
"ProgressiveRegion data short for region->cQuant");
return -1018; return -1018;
} }
len -= region->numQuant * 5ULL; len -= region->numQuant * 5LL;
if (len / 16 < region->numProgQuant) if (len / 16LL < region->numProgQuant)
{ {
WLog_Print(progressive->log, WLOG_ERROR, WLog_Print(progressive->log, WLOG_ERROR,
"ProgressiveRegion data short for region->cProgQuant"); "ProgressiveRegion data short for region->cProgQuant");
return -1021; return -1021;
} }
len -= region->numProgQuant * 16ULL; len -= region->numProgQuant * 16LL;
if (len < region->tileDataSize * 1ll) if (len < region->tileDataSize * 1ll)
{ {
WLog_Print(progressive->log, WLOG_ERROR, "ProgressiveRegion data short for region->tiles"); WLog_Print(progressive->log, WLOG_ERROR,
"ProgressiveRegion data short for region->tiles");
return -1024; return -1024;
} }
len -= region->tileDataSize; len -= region->tileDataSize;
if (len > 0) if (len > 0)
WLog_Print(progressive->log, WLOG_WARN, WLog_Print(progressive->log, WLOG_WARN,
"Unused bytes detected, %" PRIuz " bytes not processed", len); "Unused bytes detected, %" PRIdz " bytes not processed", len);
return len; }
return rc;
} }
static INLINE SSIZE_T progressive_wb_skip_region(PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive, static INLINE SSIZE_T progressive_wb_skip_region(PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive,
wStream* WINPR_RESTRICT s, UINT16 blockType, wStream* WINPR_RESTRICT s, UINT16 blockType,
UINT32 blockLen) UINT32 blockLen)
{ {
SSIZE_T rc = 0; PROGRESSIVE_BLOCK_REGION* WINPR_RESTRICT region = &progressive->region;
size_t total = 0;
PROGRESSIVE_BLOCK_REGION* region = &progressive->region;
rc = progressive_wb_read_region_header(progressive, s, blockType, blockLen, region); const SSIZE_T rc =
progressive_wb_read_region_header(progressive, s, blockType, blockLen, region);
if (rc < 0) if (rc < 0)
return rc; return rc;
total = (region->numRects * 8); if (!Stream_SafeSeek(s, rc))
total += (region->numQuant * 5);
total += (region->numProgQuant * 16);
total += region->tileDataSize;
if (!Stream_SafeSeek(s, total))
return -1111; return -1111;
return rc; return rc;
@ -2268,7 +2243,7 @@ static INLINE SSIZE_T progressive_wb_region(PROGRESSIVE_CONTEXT* WINPR_RESTRICT
return (size_t)rc; return (size_t)rc;
} }
static SSIZE_T progressive_parse_block(PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive, static INLINE SSIZE_T progressive_parse_block(PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive,
wStream* WINPR_RESTRICT s, wStream* WINPR_RESTRICT s,
PROGRESSIVE_SURFACE_CONTEXT* WINPR_RESTRICT surface, PROGRESSIVE_SURFACE_CONTEXT* WINPR_RESTRICT surface,
PROGRESSIVE_BLOCK_REGION* WINPR_RESTRICT region) PROGRESSIVE_BLOCK_REGION* WINPR_RESTRICT region)
@ -2337,7 +2312,7 @@ static SSIZE_T progressive_parse_block(PROGRESSIVE_CONTEXT* WINPR_RESTRICT progr
return rc; return rc;
} }
static BOOL update_tiles(PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive, static INLINE BOOL update_tiles(PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive,
PROGRESSIVE_SURFACE_CONTEXT* WINPR_RESTRICT surface, PROGRESSIVE_SURFACE_CONTEXT* WINPR_RESTRICT surface,
BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep, BYTE* WINPR_RESTRICT pDstData, UINT32 DstFormat, UINT32 nDstStep,
UINT32 nXDst, UINT32 nYDst, UINT32 nXDst, UINT32 nYDst,
@ -2434,7 +2409,7 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* WINPR_RESTRICT progressive,
return -1001; return -1001;
} }
PROGRESSIVE_BLOCK_REGION* region = &progressive->region; PROGRESSIVE_BLOCK_REGION* WINPR_RESTRICT region = &progressive->region;
WINPR_ASSERT(region); WINPR_ASSERT(region);
if (surface->frameId != frameId) if (surface->frameId != frameId)

View File

@ -22,6 +22,7 @@
#define INTERNAL_CODEC_PROGRESSIVE_H #define INTERNAL_CODEC_PROGRESSIVE_H
#include <winpr/wlog.h> #include <winpr/wlog.h>
#include <winpr/pool.h>
#include <winpr/collections.h> #include <winpr/collections.h>
#include <freerdp/codec/rfx.h> #include <freerdp/codec/rfx.h>
@ -139,7 +140,18 @@ typedef struct
RFX_COMPONENT_CODEC_QUANT crProgQuant; RFX_COMPONENT_CODEC_QUANT crProgQuant;
} RFX_PROGRESSIVE_TILE; } RFX_PROGRESSIVE_TILE;
typedef struct S_PROGRESSIVE_CONTEXT PROGRESSIVE_CONTEXT;
typedef struct S_PROGRESSIVE_BLOCK_REGION PROGRESSIVE_BLOCK_REGION;
typedef struct typedef struct
{
PROGRESSIVE_CONTEXT* progressive;
PROGRESSIVE_BLOCK_REGION* region;
const PROGRESSIVE_BLOCK_CONTEXT* context;
RFX_PROGRESSIVE_TILE* tile;
} PROGRESSIVE_TILE_PROCESS_WORK_PARAM;
struct S_PROGRESSIVE_BLOCK_REGION
{ {
UINT16 blockType; UINT16 blockType;
UINT32 blockLen; UINT32 blockLen;
@ -156,7 +168,7 @@ typedef struct
RFX_COMPONENT_CODEC_QUANT quantVals[0x100]; RFX_COMPONENT_CODEC_QUANT quantVals[0x100];
RFX_PROGRESSIVE_CODEC_QUANT quantProgVals[0x100]; RFX_PROGRESSIVE_CODEC_QUANT quantProgVals[0x100];
RFX_PROGRESSIVE_TILE* tiles[0x10000]; RFX_PROGRESSIVE_TILE* tiles[0x10000];
} PROGRESSIVE_BLOCK_REGION; };
typedef struct typedef struct
{ {
@ -216,6 +228,8 @@ struct S_PROGRESSIVE_CONTEXT
wStream* buffer; wStream* buffer;
wStream* rects; wStream* rects;
RFX_CONTEXT* rfx_context; RFX_CONTEXT* rfx_context;
PROGRESSIVE_TILE_PROCESS_WORK_PARAM params[0x10000];
PTP_WORK work_objects[0x10000];
}; };
#endif /* INTERNAL_CODEC_PROGRESSIVE_H */ #endif /* INTERNAL_CODEC_PROGRESSIVE_H */