From f2d09e6eb06fc4afbe36720d9936c243465bd29b Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 4 Feb 2021 13:01:38 +0800 Subject: [PATCH] progressive: fix multiple regions in one gfx frame. (cherry picked from commit 7f94095a0670f6d0bc19021e6e1439cf934edf52) --- include/freerdp/codec/progressive.h | 3 ++- include/freerdp/gdi/gdi.h | 1 + libfreerdp/codec/progressive.c | 27 +++++++++++++++++----- libfreerdp/codec/progressive.h | 3 +++ .../codec/test/TestFreeRDPCodecProgressive.c | 7 +++--- libfreerdp/gdi/gfx.c | 3 ++- 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/include/freerdp/codec/progressive.h b/include/freerdp/codec/progressive.h index 37b289a..57a81f9 100644 --- a/include/freerdp/codec/progressive.h +++ b/include/freerdp/codec/progressive.h @@ -46,7 +46,8 @@ extern "C" FREERDP_API INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, UINT32 nYDst, - REGION16* invalidRegion, UINT16 surfaceId); + REGION16* invalidRegion, UINT16 surfaceId, + UINT32 frameId); FREERDP_API INT32 progressive_create_surface_context(PROGRESSIVE_CONTEXT* progressive, UINT16 surfaceId, UINT32 width, diff --git a/include/freerdp/gdi/gdi.h b/include/freerdp/gdi/gdi.h index ddb310b..790f5df 100644 --- a/include/freerdp/gdi/gdi.h +++ b/include/freerdp/gdi/gdi.h @@ -520,6 +520,7 @@ struct rdp_gdi BOOL graphicsReset; /* deprecated, remove with FreeRDP v3 */ BOOL suppressOutput; UINT16 outputSurfaceId; + UINT32 frameId; RdpgfxClientContext* gfx; VideoClientContext* video; GeometryClientContext* geometry; diff --git a/libfreerdp/codec/progressive.c b/libfreerdp/codec/progressive.c index d67b11f..da2ac78 100644 --- a/libfreerdp/codec/progressive.c +++ b/libfreerdp/codec/progressive.c @@ -396,6 +396,7 @@ static void progressive_surface_context_free(PROGRESSIVE_SURFACE_CONTEXT* surfac } free(surface->tiles); + free(surface->updatedTileIndices); free(surface); } @@ -449,8 +450,9 @@ static PROGRESSIVE_SURFACE_CONTEXT* progressive_surface_context_new(UINT16 surfa surface->gridHeight = (height + (64 - height % 64)) / 64; surface->gridSize = surface->gridWidth * surface->gridHeight; surface->tiles = (RFX_PROGRESSIVE_TILE*)calloc(surface->gridSize, sizeof(RFX_PROGRESSIVE_TILE)); + surface->updatedTileIndices = (UINT32*)calloc(surface->gridSize, sizeof(UINT32)); - if (!surface->tiles) + if (!surface->tiles || !surface->updatedTileIndices) { free(surface); return NULL; @@ -542,8 +544,14 @@ static BOOL progressive_surface_tile_replace(PROGRESSIVE_SURFACE_CONTEXT* surfac region->numTiles, region->usedTiles); return FALSE; } + if (surface->numUpdatedTiles >= surface->gridSize) + { + WLog_ERR(TAG, "Invalid total tile count, maximum %" PRIu32, surface->gridSize); + return FALSE; + } region->tiles[region->usedTiles++] = t; + surface->updatedTileIndices[surface->numUpdatedTiles++] = (UINT32)zIdx; return TRUE; } @@ -1732,7 +1740,7 @@ static INLINE int progressive_process_tiles(PROGRESSIVE_CONTEXT* progressive, wS } } - return (int)end - start; + return (int)(end - start); } static INLINE INT32 progressive_wb_sync(PROGRESSIVE_CONTEXT* progressive, wStream* s, @@ -2146,10 +2154,11 @@ static INLINE INT32 progressive_wb_region(PROGRESSIVE_CONTEXT* progressive, wStr INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcData, UINT32 SrcSize, BYTE* pDstData, UINT32 DstFormat, UINT32 nDstStep, UINT32 nXDst, - UINT32 nYDst, REGION16* invalidRegion, UINT16 surfaceId) + UINT32 nYDst, REGION16* invalidRegion, UINT16 surfaceId, + UINT32 frameId) { INT32 rc = 1; - UINT16 i, j; + UINT32 i, j; UINT16 blockType; UINT32 blockLen; UINT32 count = 0; @@ -2172,6 +2181,12 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD return -1001; } + if (surface->frameId != frameId) + { + surface->frameId = frameId; + surface->numUpdatedTiles = 0; + } + Stream_StaticInit(&ss, sconv.bp, SrcSize); s = &ss; @@ -2274,12 +2289,12 @@ INT32 progressive_decompress(PROGRESSIVE_CONTEXT* progressive, const BYTE* pSrcD region16_union_rect(&clippingRects, &clippingRects, &clippingRect); } - for (i = 0; i < region->numTiles; i++) + for (i = 0; i < surface->numUpdatedTiles; i++) { UINT32 nbUpdateRects; const RECTANGLE_16* updateRects; RECTANGLE_16 updateRect; - RFX_PROGRESSIVE_TILE* tile = region->tiles[i]; + RFX_PROGRESSIVE_TILE* tile = &surface->tiles[surface->updatedTileIndices[i]]; updateRect.left = nXDst + tile->x; updateRect.top = nYDst + tile->y; diff --git a/libfreerdp/codec/progressive.h b/libfreerdp/codec/progressive.h index 418af40..3b4469b 100644 --- a/libfreerdp/codec/progressive.h +++ b/libfreerdp/codec/progressive.h @@ -200,6 +200,9 @@ struct _PROGRESSIVE_SURFACE_CONTEXT UINT32 gridHeight; UINT32 gridSize; RFX_PROGRESSIVE_TILE* tiles; + UINT32 frameId; + UINT32 numUpdatedTiles; + UINT32* updatedTileIndices; }; typedef struct _PROGRESSIVE_SURFACE_CONTEXT PROGRESSIVE_SURFACE_CONTEXT; diff --git a/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c b/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c index 54e3e83..f9ab7b6 100644 --- a/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c +++ b/libfreerdp/codec/test/TestFreeRDPCodecProgressive.c @@ -839,8 +839,9 @@ static int test_progressive_decode(PROGRESSIVE_CONTEXT* progressive, EGFX_SAMPLE for (pass = 0; pass < count; pass++) { - status = progressive_decompress(progressive, files[pass].buffer, files[pass].size, - g_DstData, PIXEL_FORMAT_XRGB32, g_DstStep, 0, 0, NULL, 0); + status = + progressive_decompress(progressive, files[pass].buffer, files[pass].size, g_DstData, + PIXEL_FORMAT_XRGB32, g_DstStep, 0, 0, NULL, 0, 0); printf("ProgressiveDecompress: status: %d pass: %d\n", status, pass + 1); region = &(progressive->region); @@ -1077,7 +1078,7 @@ static BOOL test_encode_decode(const char* path) goto fail; rc = progressive_decompress(progressiveDec, dstData, dstSize, resultData, ColorFormat, - image->scanline, 0, 0, &invalidRegion, 0); + image->scanline, 0, 0, &invalidRegion, 0, 0); if (rc < 0) goto fail; diff --git a/libfreerdp/gdi/gfx.c b/libfreerdp/gdi/gfx.c index c210332..3d50c80 100644 --- a/libfreerdp/gdi/gfx.c +++ b/libfreerdp/gdi/gfx.c @@ -221,6 +221,7 @@ static UINT gdi_StartFrame(RdpgfxClientContext* context, const RDPGFX_START_FRAM { rdpGdi* gdi = (rdpGdi*)context->custom; gdi->inGfxFrame = TRUE; + gdi->frameId = startFrame->frameId; return CHANNEL_RC_OK; } @@ -826,7 +827,7 @@ static UINT gdi_SurfaceCommand_Progressive(rdpGdi* gdi, RdpgfxClientContext* con region16_init(&invalidRegion); rc = progressive_decompress(surface->codecs->progressive, cmd->data, cmd->length, surface->data, surface->format, surface->scanline, cmd->left, cmd->top, - &invalidRegion, cmd->surfaceId); + &invalidRegion, cmd->surfaceId, gdi->frameId); if (rc < 0) { -- 2.7.4