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 13 years ago
parent 67b16cdf90
commit 9f49600787

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

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

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

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

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

@ -11,19 +11,13 @@
#include "minilzo.h" #include "minilzo.h"
/* /*
* lzoBeforeBuf contains pixel data in the client's format. * cl->beforeEncBuf contains pixel data in the client's format.
* lzoAfterBuf contains the lzo (deflated) encoding version. * cl->afterEncBuf contains the lzo (deflated) encoding version.
* If the lzo compressed/encoded version is * 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. * 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 * 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) #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) { void rfbFreeUltraData(rfbClientPtr cl) {
if (cl->compStreamInitedLZO) { if (cl->compStreamInitedLZO) {
@ -71,12 +54,12 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
maxRawSize = (w * h * (cl->format.bitsPerPixel / 8)); maxRawSize = (w * h * (cl->format.bitsPerPixel / 8));
if (lzoBeforeBufSize < maxRawSize) { if (cl->beforeEncBufSize < maxRawSize) {
lzoBeforeBufSize = maxRawSize; cl->beforeEncBufSize = maxRawSize;
if (lzoBeforeBuf == NULL) if (cl->beforeEncBuf == NULL)
lzoBeforeBuf = (char *)malloc(lzoBeforeBufSize); cl->beforeEncBuf = (char *)malloc(cl->beforeEncBufSize);
else 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); maxCompSize = (maxRawSize + maxRawSize / 16 + 64 + 3);
if (lzoAfterBufSize < maxCompSize) { if (cl->afterEncBufSize < maxCompSize) {
lzoAfterBufSize = maxCompSize; cl->afterEncBufSize = maxCompSize;
if (lzoAfterBuf == NULL) if (cl->afterEncBuf == NULL)
lzoAfterBuf = (char *)malloc(lzoAfterBufSize); cl->afterEncBuf = (char *)malloc(cl->afterEncBufSize);
else else
lzoAfterBuf = (char *)realloc(lzoAfterBuf, lzoAfterBufSize); cl->afterEncBuf = (char *)realloc(cl->afterEncBuf, cl->afterEncBufSize);
} }
/* /*
* Convert pixel data to client format. * Convert pixel data to client format.
*/ */
(*cl->translateFn)(cl->translateLookupTable, &cl->screen->serverFormat, (*cl->translateFn)(cl->translateLookupTable, &cl->screen->serverFormat,
&cl->format, fbptr, lzoBeforeBuf, &cl->format, fbptr, cl->beforeEncBuf,
cl->scaledScreen->paddedWidthInBytes, w, h); cl->scaledScreen->paddedWidthInBytes, w, h);
if ( cl->compStreamInitedLZO == FALSE ) { if ( cl->compStreamInitedLZO == FALSE ) {
@ -109,11 +92,11 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
} }
/* Perform the compression here. */ /* 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 */ /* maxCompSize now contains the compressed size */
/* Find the total size of the resulting compressed data. */ /* Find the total size of the resulting compressed data. */
lzoAfterBufLen = maxCompSize; cl->afterEncBufLen = maxCompSize;
if ( deflateResult != LZO_E_OK ) { if ( deflateResult != LZO_E_OK ) {
rfbErr("lzo deflation error: %d\n", deflateResult); rfbErr("lzo deflation error: %d\n", deflateResult);
@ -121,7 +104,7 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
} }
/* Update statics */ /* 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 if (cl->ublen + sz_rfbFramebufferUpdateRectHeader + sz_rfbZlibHeader
> UPDATE_BUF_SIZE) > UPDATE_BUF_SIZE)
@ -140,21 +123,21 @@ rfbSendOneRectEncodingUltra(rfbClientPtr cl,
sz_rfbFramebufferUpdateRectHeader); sz_rfbFramebufferUpdateRectHeader);
cl->ublen += sz_rfbFramebufferUpdateRectHeader; cl->ublen += sz_rfbFramebufferUpdateRectHeader;
hdr.nBytes = Swap32IfLE(lzoAfterBufLen); hdr.nBytes = Swap32IfLE(cl->afterEncBufLen);
memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbZlibHeader); memcpy(&cl->updateBuf[cl->ublen], (char *)&hdr, sz_rfbZlibHeader);
cl->ublen += sz_rfbZlibHeader; cl->ublen += sz_rfbZlibHeader;
/* We might want to try sending the data directly... */ /* 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; int bytesToCopy = UPDATE_BUF_SIZE - cl->ublen;
if (i + bytesToCopy > lzoAfterBufLen) { if (i + bytesToCopy > cl->afterEncBufLen) {
bytesToCopy = lzoAfterBufLen - i; bytesToCopy = cl->afterEncBufLen - i;
} }
memcpy(&cl->updateBuf[cl->ublen], &lzoAfterBuf[i], bytesToCopy); memcpy(&cl->updateBuf[cl->ublen], &cl->afterEncBuf[i], bytesToCopy);
cl->ublen += bytesToCopy; cl->ublen += bytesToCopy;
i += bytesToCopy; i += bytesToCopy;

@ -617,6 +617,13 @@ typedef struct _rfbClientRec {
MUTEX(sendMutex); MUTEX(sendMutex);
#endif #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; } rfbClientRec, *rfbClientPtr;
/** /**

Loading…
Cancel
Save