libvncserver: Make RRE, CoRRE and Ultra encodings thread-safe.

This adds generic before/after encoding buffers to the rfbClient
struct, so there is no need for thread local storage.

Signed-off-by: Christian Beier <dontmind@freeshell.org>
pull/1/head
Christian Beier 12 years ago
parent 67b16cdf90
commit 9f49600787
  1. 88
      libvncserver/corre.c
  2. 3
      libvncserver/main.c
  3. 9
      libvncserver/private.h
  4. 4
      libvncserver/rfbserver.c
  5. 90
      libvncserver/rre.c
  6. 61
      libvncserver/ultra.c
  7. 7
      rfb/rfb.h

@ -30,37 +30,19 @@
#include <rfb/rfb.h>
/*
* rreBeforeBuf contains pixel data in the client's format.
* rreAfterBuf contains the RRE encoded version. If the RRE encoded version is
* larger than the raw data or if it exceeds rreAfterBufSize then
* cl->beforeEncBuf contains pixel data in the client's format.
* cl->afterEncBuf contains the RRE encoded version. If the RRE encoded version is
* larger than the raw data or if it exceeds cl->afterEncBufSize then
* raw encoding is used instead.
*/
static int rreBeforeBufSize = 0;
static char *rreBeforeBuf = NULL;
static int rreAfterBufSize = 0;
static char *rreAfterBuf = NULL;
static int rreAfterBufLen = 0;
static int subrectEncode8(uint8_t *data, int w, int h);
static int subrectEncode16(uint16_t *data, int w, int h);
static int subrectEncode32(uint32_t *data, int w, int h);
static int subrectEncode8(rfbClientPtr cl, uint8_t *data, int w, int h);
static int subrectEncode16(rfbClientPtr cl, uint16_t *data, int w, int h);
static int subrectEncode32(rfbClientPtr cl, uint32_t *data, int w, int h);
static uint32_t getBgColour(char *data, int size, int bpp);
static rfbBool rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl, int x, int y,
int w, int h);
void rfbCoRRECleanup(rfbScreenInfoPtr screen)
{
if (rreBeforeBufSize) {
free(rreBeforeBuf);
rreBeforeBufSize=0;
}
if (rreAfterBufSize) {
free(rreAfterBuf);
rreAfterBufSize=0;
}
}
/*
* rfbSendRectEncodingCoRRE - send an arbitrary size rectangle using CoRRE
@ -114,35 +96,35 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl,
int maxRawSize = (cl->scaledScreen->width * cl->scaledScreen->height
* (cl->format.bitsPerPixel / 8));
if (rreBeforeBufSize < maxRawSize) {
rreBeforeBufSize = maxRawSize;
if (rreBeforeBuf == NULL)
rreBeforeBuf = (char *)malloc(rreBeforeBufSize);
if (cl->beforeEncBufSize < maxRawSize) {
cl->beforeEncBufSize = maxRawSize;
if (cl->beforeEncBuf == NULL)
cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize);
else
rreBeforeBuf = (char *)realloc(rreBeforeBuf, rreBeforeBufSize);
cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize);
}
if (rreAfterBufSize < maxRawSize) {
rreAfterBufSize = maxRawSize;
if (rreAfterBuf == NULL)
rreAfterBuf = (char *)malloc(rreAfterBufSize);
if (cl->afterEncBufSize < maxRawSize) {
cl->afterEncBufSize = maxRawSize;
if (cl->afterEncBuf == NULL)
cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize);
else
rreAfterBuf = (char *)realloc(rreAfterBuf, rreAfterBufSize);
cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize);
}
(*cl->translateFn)(cl->translateLookupTable,&(cl->screen->serverFormat),
&cl->format, fbptr, rreBeforeBuf,
&cl->format, fbptr, cl->beforeEncBuf,
cl->scaledScreen->paddedWidthInBytes, w, h);
switch (cl->format.bitsPerPixel) {
case 8:
nSubrects = subrectEncode8((uint8_t *)rreBeforeBuf, w, h);
nSubrects = subrectEncode8(cl, (uint8_t *)cl->beforeEncBuf, w, h);
break;
case 16:
nSubrects = subrectEncode16((uint16_t *)rreBeforeBuf, w, h);
nSubrects = subrectEncode16(cl, (uint16_t *)cl->beforeEncBuf, w, h);
break;
case 32:
nSubrects = subrectEncode32((uint32_t *)rreBeforeBuf, w, h);
nSubrects = subrectEncode32(cl, (uint32_t *)cl->beforeEncBuf, w, h);
break;
default:
rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel);
@ -157,7 +139,7 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl,
}
rfbStatRecordEncodingSent(cl,rfbEncodingCoRRE,
sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + rreAfterBufLen,
sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + cl->afterEncBufLen,
sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8));
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader
@ -182,15 +164,15 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl,
memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader);
cl->ublen += sz_rfbRREHeader;
for (i = 0; i < rreAfterBufLen;) {
for (i = 0; i < cl->afterEncBufLen;) {
int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
if (i + bytesToCopy > rreAfterBufLen) {
bytesToCopy = rreAfterBufLen - i;
if (i + bytesToCopy > cl->afterEncBufLen) {
bytesToCopy = cl->afterEncBufLen - i;
}
memcpy(&cl->updateBuf[cl->ublen], &rreAfterBuf[i], bytesToCopy);
memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy);
cl->ublen += bytesToCopy;
i += bytesToCopy;
@ -210,7 +192,7 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl,
* subrectEncode() encodes the given multicoloured rectangle as a background
* colour overwritten by single-coloured rectangles. It returns the number
* of subrectangles in the encoded buffer, or -1 if subrect encoding won't
* fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The
* fit in the buffer. It puts the encoded rectangles in cl->afterEncBuf. The
* single-colour rectangle partition is not optimal, but does find the biggest
* horizontal or vertical rectangle top-left anchored to each consecutive
* coordinate position.
@ -221,7 +203,7 @@ rfbSendSmallRectEncodingCoRRE(rfbClientPtr cl,
#define DEFINE_SUBRECT_ENCODE(bpp) \
static int \
subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \
subrectEncode##bpp(rfbClientPtr client, uint##bpp##_t *data, int w, int h) { \
uint##bpp##_t cl; \
rfbCoRRERectangle subrect; \
int x,y; \
@ -236,9 +218,9 @@ subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \
int newLen; \
uint##bpp##_t bg = (uint##bpp##_t)getBgColour((char*)data,w*h,bpp); \
\
*((uint##bpp##_t*)rreAfterBuf) = bg; \
*((uint##bpp##_t*)client->afterEncBuf) = bg; \
\
rreAfterBufLen = (bpp/8); \
client->afterEncBufLen = (bpp/8); \
\
for (y=0; y<h; y++) { \
line = data+(y*w); \
@ -283,15 +265,15 @@ subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \
subrect.w = thew; \
subrect.h = theh; \
\
newLen = rreAfterBufLen + (bpp/8) + sz_rfbCoRRERectangle; \
if ((newLen > (w * h * (bpp/8))) || (newLen > rreAfterBufSize)) \
newLen = client->afterEncBufLen + (bpp/8) + sz_rfbCoRRERectangle; \
if ((newLen > (w * h * (bpp/8))) || (newLen > client->afterEncBufSize)) \
return -1; \
\
numsubs += 1; \
*((uint##bpp##_t*)(rreAfterBuf + rreAfterBufLen)) = cl; \
rreAfterBufLen += (bpp/8); \
memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbCoRRERectangle); \
rreAfterBufLen += sz_rfbCoRRERectangle; \
*((uint##bpp##_t*)(client->afterEncBuf + client->afterEncBufLen)) = cl; \
client->afterEncBufLen += (bpp/8); \
memcpy(&client->afterEncBuf[client->afterEncBufLen],&subrect,sz_rfbCoRRERectangle); \
client->afterEncBufLen += sz_rfbCoRRERectangle; \
\
/* \
* Now mark the subrect as done. \

@ -1003,9 +1003,6 @@ void rfbScreenCleanup(rfbScreenInfoPtr screen)
if(screen->cursor && screen->cursor->cleanup)
rfbFreeCursor(screen->cursor);
rfbRRECleanup(screen);
rfbCoRRECleanup(screen);
rfbUltraCleanup(screen);
#ifdef LIBVNCSERVER_HAVE_LIBZ
rfbZlibCleanup(screen);
#ifdef LIBVNCSERVER_HAVE_LIBJPEG

@ -29,16 +29,7 @@ void rfbFreeZrleData(rfbClientPtr cl);
/* from ultra.c */
extern void rfbUltraCleanup(rfbScreenInfoPtr screen);
extern void rfbFreeUltraData(rfbClientPtr cl);
/* from rre.c */
extern void rfbRRECleanup(rfbScreenInfoPtr screen);
/* from corre.c */
extern void rfbCoRRECleanup(rfbScreenInfoPtr screen);
#endif

@ -486,6 +486,10 @@ rfbClientConnectionGone(rfbClientPtr cl)
rfbFreeUltraData(cl);
/* free buffers holding pixel data before and after encoding */
free(cl->beforeEncBuf);
free(cl->afterEncBuf);
#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD
if(cl->screen->backgroundLoop != FALSE) {
int i;

@ -29,38 +29,18 @@
#include <rfb/rfb.h>
/*
* rreBeforeBuf contains pixel data in the client's format.
* rreAfterBuf contains the RRE encoded version. If the RRE encoded version is
* larger than the raw data or if it exceeds rreAfterBufSize then
* cl->beforeEncBuf contains pixel data in the client's format.
* cl->afterEncBuf contains the RRE encoded version. If the RRE encoded version is
* larger than the raw data or if it exceeds cl->afterEncBufSize then
* raw encoding is used instead.
*/
static int rreBeforeBufSize = 0;
static char *rreBeforeBuf = NULL;
static int rreAfterBufSize = 0;
static char *rreAfterBuf = NULL;
static int rreAfterBufLen=0;
static int subrectEncode8(uint8_t *data, int w, int h);
static int subrectEncode16(uint16_t *data, int w, int h);
static int subrectEncode32(uint32_t *data, int w, int h);
static int subrectEncode8(rfbClientPtr cl, uint8_t *data, int w, int h);
static int subrectEncode16(rfbClientPtr cl, uint16_t *data, int w, int h);
static int subrectEncode32(rfbClientPtr cl, uint32_t *data, int w, int h);
static uint32_t getBgColour(char *data, int size, int bpp);
void rfbRRECleanup(rfbScreenInfoPtr screen)
{
if (rreBeforeBufSize) {
free(rreBeforeBuf);
rreBeforeBufSize=0;
}
if (rreAfterBufSize) {
free(rreAfterBuf);
rreAfterBufSize=0;
}
}
/*
* rfbSendRectEncodingRRE - send a given rectangle using RRE encoding.
*/
@ -82,36 +62,36 @@ rfbSendRectEncodingRRE(rfbClientPtr cl,
int maxRawSize = (cl->scaledScreen->width * cl->scaledScreen->height
* (cl->format.bitsPerPixel / 8));
if (rreBeforeBufSize < maxRawSize) {
rreBeforeBufSize = maxRawSize;
if (rreBeforeBuf == NULL)
rreBeforeBuf = (char *)malloc(rreBeforeBufSize);
if (cl->beforeEncBufSize < maxRawSize) {
cl->beforeEncBufSize = maxRawSize;
if (cl->beforeEncBuf == NULL)
cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize);
else
rreBeforeBuf = (char *)realloc(rreBeforeBuf, rreBeforeBufSize);
cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize);
}
if (rreAfterBufSize < maxRawSize) {
rreAfterBufSize = maxRawSize;
if (rreAfterBuf == NULL)
rreAfterBuf = (char *)malloc(rreAfterBufSize);
if (cl->afterEncBufSize < maxRawSize) {
cl->afterEncBufSize = maxRawSize;
if (cl->afterEncBuf == NULL)
cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize);
else
rreAfterBuf = (char *)realloc(rreAfterBuf, rreAfterBufSize);
cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize);
}
(*cl->translateFn)(cl->translateLookupTable,
&(cl->screen->serverFormat),
&cl->format, fbptr, rreBeforeBuf,
&cl->format, fbptr, cl->beforeEncBuf,
cl->scaledScreen->paddedWidthInBytes, w, h);
switch (cl->format.bitsPerPixel) {
case 8:
nSubrects = subrectEncode8((uint8_t *)rreBeforeBuf, w, h);
nSubrects = subrectEncode8(cl, (uint8_t *)cl->beforeEncBuf, w, h);
break;
case 16:
nSubrects = subrectEncode16((uint16_t *)rreBeforeBuf, w, h);
nSubrects = subrectEncode16(cl, (uint16_t *)cl->beforeEncBuf, w, h);
break;
case 32:
nSubrects = subrectEncode32((uint32_t *)rreBeforeBuf, w, h);
nSubrects = subrectEncode32(cl, (uint32_t *)cl->beforeEncBuf, w, h);
break;
default:
rfbLog("getBgColour: bpp %d?\n",cl->format.bitsPerPixel);
@ -126,7 +106,7 @@ rfbSendRectEncodingRRE(rfbClientPtr cl,
}
rfbStatRecordEncodingSent(cl, rfbEncodingRRE,
sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + rreAfterBufLen,
sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader + cl->afterEncBufLen,
sz_rfbFramebufferUpdateRectHeader + w * h * (cl->format.bitsPerPixel / 8));
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbRREHeader
@ -151,15 +131,15 @@ rfbSendRectEncodingRRE(rfbClientPtr cl,
memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbRREHeader);
cl->ublen += sz_rfbRREHeader;
for (i = 0; i < rreAfterBufLen;) {
for (i = 0; i < cl->afterEncBufLen;) {
int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
if (i + bytesToCopy > rreAfterBufLen) {
bytesToCopy = rreAfterBufLen - i;
if (i + bytesToCopy > cl->afterEncBufLen) {
bytesToCopy = cl->afterEncBufLen - i;
}
memcpy(&cl->updateBuf[cl->ublen], &rreAfterBuf[i], bytesToCopy);
memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy);
cl->ublen += bytesToCopy;
i += bytesToCopy;
@ -179,7 +159,7 @@ rfbSendRectEncodingRRE(rfbClientPtr cl,
* subrectEncode() encodes the given multicoloured rectangle as a background
* colour overwritten by single-coloured rectangles. It returns the number
* of subrectangles in the encoded buffer, or -1 if subrect encoding won't
* fit in the buffer. It puts the encoded rectangles in rreAfterBuf. The
* fit in the buffer. It puts the encoded rectangles in cl->afterEncBuf. The
* single-colour rectangle partition is not optimal, but does find the biggest
* horizontal or vertical rectangle top-left anchored to each consecutive
* coordinate position.
@ -190,7 +170,7 @@ rfbSendRectEncodingRRE(rfbClientPtr cl,
#define DEFINE_SUBRECT_ENCODE(bpp) \
static int \
subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \
subrectEncode##bpp(rfbClientPtr client, uint##bpp##_t *data, int w, int h) { \
uint##bpp##_t cl; \
rfbRectangle subrect; \
int x,y; \
@ -205,9 +185,9 @@ subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \
int newLen; \
uint##bpp##_t bg = (uint##bpp##_t)getBgColour((char*)data,w*h,bpp); \
\
*((uint##bpp##_t*)rreAfterBuf) = bg; \
*((uint##bpp##_t*)client->afterEncBuf) = bg; \
\
rreAfterBufLen = (bpp/8); \
client->afterEncBufLen = (bpp/8); \
\
for (y=0; y<h; y++) { \
line = data+(y*w); \
@ -252,15 +232,15 @@ subrectEncode##bpp(uint##bpp##_t *data, int w, int h) { \
subrect.w = Swap16IfLE(thew); \
subrect.h = Swap16IfLE(theh); \
\
newLen = rreAfterBufLen + (bpp/8) + sz_rfbRectangle; \
if ((newLen > (w * h * (bpp/8))) || (newLen > rreAfterBufSize)) \
newLen = client->afterEncBufLen + (bpp/8) + sz_rfbRectangle; \
if ((newLen > (w * h * (bpp/8))) || (newLen > client->afterEncBufSize)) \
return -1; \
\
numsubs += 1; \
*((uint##bpp##_t*)(rreAfterBuf + rreAfterBufLen)) = cl; \
rreAfterBufLen += (bpp/8); \
memcpy(&rreAfterBuf[rreAfterBufLen],&subrect,sz_rfbRectangle); \
rreAfterBufLen += sz_rfbRectangle; \
*((uint##bpp##_t*)(client->afterEncBuf + client->afterEncBufLen)) = cl; \
client->afterEncBufLen += (bpp/8); \
memcpy(&client->afterEncBuf[client->afterEncBufLen],&subrect,sz_rfbRectangle); \
client->afterEncBufLen += sz_rfbRectangle; \
\
/* \
* Now mark the subrect as done. \

@ -11,19 +11,13 @@
#include "minilzo.h"
/*
* lzoBeforeBuf contains pixel data in the client's format.
* lzoAfterBuf contains the lzo (deflated) encoding version.
* cl->beforeEncBuf contains pixel data in the client's format.
* cl->afterEncBuf contains the lzo (deflated) encoding version.
* If the lzo compressed/encoded version is
* larger than the raw data or if it exceeds lzoAfterBufSize then
* larger than the raw data or if it exceeds cl->afterEncBufSize then
* raw encoding is used instead.
*/
static int lzoBeforeBufSize = 0;
static char *lzoBeforeBuf = NULL;
static int lzoAfterBufSize = 0;
static char *lzoAfterBuf = NULL;
static int lzoAfterBufLen = 0;
/*
* rfbSendOneRectEncodingZlib - send a given rectangle using one Zlib
@ -32,17 +26,6 @@ static int lzoAfterBufLen = 0;
#define MAX_WRKMEM ((LZO1X_1_MEM_COMPRESS) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t)
void rfbUltraCleanup(rfbScreenInfoPtr screen)
{
if (lzoBeforeBufSize) {
free(lzoBeforeBuf);
lzoBeforeBufSize=0;
}
if (lzoAfterBufSize) {
free(lzoAfterBuf);
lzoAfterBufSize=0;
}
}
void rfbFreeUltraData(rfbClientPtr cl) {
if (cl->compStreamInitedLZO) {
@ -71,12 +54,12 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
maxRawSize = (w * h * (cl->format.bitsPerPixel / 8));
if (lzoBeforeBufSize < maxRawSize) {
lzoBeforeBufSize = maxRawSize;
if (lzoBeforeBuf == NULL)
lzoBeforeBuf = (char *)malloc(lzoBeforeBufSize);
if (cl->beforeEncBufSize < maxRawSize) {
cl->beforeEncBufSize = maxRawSize;
if (cl->beforeEncBuf == NULL)
cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize);
else
lzoBeforeBuf = (char *)realloc(lzoBeforeBuf, lzoBeforeBufSize);
cl->beforeEncBuf = (char *)realloc(cl->beforeEncBuf, cl->beforeEncBufSize);
}
/*
@ -85,19 +68,19 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
*/
maxCompSize = (maxRawSize + maxRawSize / 16 + 64 + 3);
if (lzoAfterBufSize < maxCompSize) {
lzoAfterBufSize = maxCompSize;
if (lzoAfterBuf == NULL)
lzoAfterBuf = (char *)malloc(lzoAfterBufSize);
if (cl->afterEncBufSize < maxCompSize) {
cl->afterEncBufSize = maxCompSize;
if (cl->afterEncBuf == NULL)
cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize);
else
lzoAfterBuf = (char *)realloc(lzoAfterBuf, lzoAfterBufSize);
cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize);
}
/*
* Convert pixel data to client format.
*/
(*cl->translateFn)(cl->translateLookupTable, &cl->screen->serverFormat,
&cl->format, fbptr, lzoBeforeBuf,
&cl->format, fbptr, cl->beforeEncBuf,
cl->scaledScreen->paddedWidthInBytes, w, h);
if ( cl->compStreamInitedLZO == FALSE ) {
@ -109,11 +92,11 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
}
/* Perform the compression here. */
deflateResult = lzo1x_1_compress((unsigned char *)lzoBeforeBuf, (lzo_uint)(w * h * (cl->format.bitsPerPixel / 8)), (unsigned char *)lzoAfterBuf, (lzo_uint *)&maxCompSize, cl->lzoWrkMem);
deflateResult = lzo1x_1_compress((unsigned char *)cl->beforeEncBuf, (lzo_uint)(w * h * (cl->format.bitsPerPixel / 8)), (unsigned char *)cl->afterEncBuf, (lzo_uint *)&maxCompSize, cl->lzoWrkMem);
/* maxCompSize now contains the compressed size */
/* Find the total size of the resulting compressed data. */
lzoAfterBufLen = maxCompSize;
cl->afterEncBufLen = maxCompSize;
if ( deflateResult != LZO_E_OK ) {
rfbErr("lzo deflation error: %d\n", deflateResult);
@ -121,7 +104,7 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
}
/* Update statics */
rfbStatRecordEncodingSent(cl, rfbEncodingUltra, sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + lzoAfterBufLen, maxRawSize);
rfbStatRecordEncodingSent(cl, rfbEncodingUltra, sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader + cl->afterEncBufLen, maxRawSize);
if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader
> UPDATE_BUF_SIZE)
@ -140,21 +123,21 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader;
hdr.nBytes = Swap32IfLE(lzoAfterBufLen);
hdr.nBytes = Swap32IfLE(cl->afterEncBufLen);
memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbZlibHeader);
cl->ublen += sz_rfbZlibHeader;
/* We might want to try sending the data directly... */
for (i = 0; i < lzoAfterBufLen;) {
for (i = 0; i < cl->afterEncBufLen;) {
int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
if (i + bytesToCopy > lzoAfterBufLen) {
bytesToCopy = lzoAfterBufLen - i;
if (i + bytesToCopy > cl->afterEncBufLen) {
bytesToCopy = cl->afterEncBufLen - i;
}
memcpy(&cl->updateBuf[cl->ublen], &lzoAfterBuf[i], bytesToCopy);
memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy);
cl->ublen += bytesToCopy;
i += bytesToCopy;

@ -617,6 +617,13 @@ typedef struct _rfbClientRec {
MUTEX(sendMutex);
#endif
/* buffers to hold pixel data before and after encoding.
per-client for thread safety */
char *beforeEncBuf;
int beforeEncBufSize;
char *afterEncBuf;
int afterEncBufSize;
int afterEncBufLen;
} rfbClientRec, *rfbClientPtr;
/**

Loading…
Cancel
Save