From d85a2bf3e6b2e55cb982b937f0c5ca5258a4e7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Sat, 25 Oct 2014 15:36:36 -0400 Subject: [PATCH] shadow: fix bitmap update fragmentation --- server/shadow/shadow_client.c | 46 ++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 2c7d35272..a5eb61970 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -162,6 +162,9 @@ BOOL shadow_client_post_connect(freerdp_peer* peer) if (settings->ColorDepth == 24) settings->ColorDepth = 16; /* disable 24bpp */ + if (settings->MultifragMaxRequestSize < 0x3F0000) + settings->NSCodec = FALSE; /* NSCodec compressor does not support fragmentation yet */ + WLog_ERR(TAG, "Client from %s is activated (%dx%d@%d)", peer->hostname, settings->DesktopWidth, settings->DesktopHeight, settings->ColorDepth); @@ -595,10 +598,47 @@ int shadow_client_send_bitmap_update(rdpShadowClient* client, rdpShadowSurface* if (updateSizeEstimate > maxUpdateSize) { - fprintf(stderr, "update size estimate larger than maximum update size\n"); - } + UINT32 i, j; + UINT32 updateSize; + UINT32 newUpdateSize; + BITMAP_DATA* fragBitmapData; - IFCALL(update->BitmapUpdate, context, &bitmapUpdate); + fragBitmapData = (BITMAP_DATA*) malloc(sizeof(BITMAP_DATA) * k); + bitmapUpdate.rectangles = fragBitmapData; + + i = j = 0; + updateSize = 1024; + + while (i < k) + { + newUpdateSize = updateSize + (bitmapData[i].bitmapLength + 16); + + if ((newUpdateSize < maxUpdateSize) && ((i + 1) < k)) + { + CopyMemory(&fragBitmapData[j++], &bitmapData[i++], sizeof(BITMAP_DATA)); + updateSize = newUpdateSize; + } + else + { + if ((i + 1) >= k) + { + CopyMemory(&fragBitmapData[j++], &bitmapData[i++], sizeof(BITMAP_DATA)); + updateSize = newUpdateSize; + } + + bitmapUpdate.count = bitmapUpdate.number = j; + IFCALL(update->BitmapUpdate, context, &bitmapUpdate); + updateSize = 1024; + j = 0; + } + } + + free(fragBitmapData); + } + else + { + IFCALL(update->BitmapUpdate, context, &bitmapUpdate); + } free(bitmapData);