forked from pool/xorg-x11-server
353 lines
14 KiB
Diff
353 lines
14 KiB
Diff
|
From: Michal Srb <msrb@suse.cz>
|
||
|
Date: Tue, 6 Sep 2011 13:08:25 +0200
|
||
|
Subject: [PATCH 4/6] VNC: Don't let VNC access the framebuffer directly any more.
|
||
|
Patch-Mainline: Currently no upstream project.
|
||
|
Git-commit: 3e0de1d95b3ffd3988016b2d3f40f577393ad046
|
||
|
Signed-off: Egbert Eich <eich@suse.de>
|
||
|
References: bnc #653915
|
||
|
|
||
|
It seems that accessing the framebuffer directly is not a good idea anymore.
|
||
|
This patch will let the tight encoding read the screen data using GetImage. It
|
||
|
may be little slower, but not dramatically - it already does few GetImage calls
|
||
|
on every repaint now.
|
||
|
|
||
|
Signed-off-by: Egbert Eich <eich@freedesktop.org>
|
||
|
---
|
||
|
hw/vnc/tight.c | 69 ++++++++++++++++++++++++++++++---------------
|
||
|
hw/vnc/vncext.c | 19 ++----------
|
||
|
hw/xfree86/vnc/vncInit.c | 11 ++-----
|
||
|
hw/xfree86/vnc/vncint.h | 2 -
|
||
|
4 files changed, 53 insertions(+), 48 deletions(-)
|
||
|
|
||
|
diff --git a/hw/vnc/tight.c b/hw/vnc/tight.c
|
||
|
index 5c54736..f27c73e 100644
|
||
|
--- a/hw/vnc/tight.c
|
||
|
+++ b/hw/vnc/tight.c
|
||
|
@@ -109,15 +109,17 @@ static unsigned char *tightAfterBuf = NULL;
|
||
|
|
||
|
static int *prevRowBuf = NULL;
|
||
|
|
||
|
+static unsigned char* fakeFrameBuffer = NULL;
|
||
|
+
|
||
|
|
||
|
/* Prototypes for static functions. */
|
||
|
|
||
|
-static void FindBestSolidArea (ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
+static void FindBestSolidArea (rfbClientPtr cl, int x, int y, int w, int h,
|
||
|
CARD32 colorValue, int *w_ptr, int *h_ptr);
|
||
|
-static void ExtendSolidArea (ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
+static void ExtendSolidArea (rfbClientPtr cl, int x, int y, int w, int h,
|
||
|
CARD32 colorValue,
|
||
|
int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr);
|
||
|
-static Bool CheckSolidTile (ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
+static Bool CheckSolidTile (rfbClientPtr cl, int x, int y, int w, int h,
|
||
|
CARD32 *colorPtr, Bool needSameColor);
|
||
|
static Bool CheckSolidTile8 (ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
CARD32 *colorPtr, Bool needSameColor);
|
||
|
@@ -126,6 +128,7 @@ static Bool CheckSolidTile16 (ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
static Bool CheckSolidTile32 (ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
CARD32 *colorPtr, Bool needSameColor);
|
||
|
|
||
|
+static Bool SendRectEncodingTight(rfbClientPtr cl, int x, int y, int w, int h);
|
||
|
static Bool SendRectSimple (rfbClientPtr cl, int x, int y, int w, int h);
|
||
|
static Bool SendSubrect (rfbClientPtr cl, int x, int y, int w, int h);
|
||
|
static Bool SendTightHeader (rfbClientPtr cl, int x, int y, int w, int h);
|
||
|
@@ -211,6 +214,25 @@ rfbSendRectEncodingTight(rfbClientPtr cl,
|
||
|
int x, int y, int w, int h)
|
||
|
{
|
||
|
VNCSCREENPTR(cl->pScreen);
|
||
|
+
|
||
|
+ /* Copy the rectangle to the fake buffer for CheckSolidTile functions. */
|
||
|
+
|
||
|
+ if(!fakeFrameBuffer) fakeFrameBuffer = malloc(pVNC->width * pVNC->height * cl->format.bitsPerPixel / 8);
|
||
|
+ (*cl->translateFn)(cl->pScreen, cl->translateLookupTable,
|
||
|
+ &pVNC->rfbServerFormat,
|
||
|
+ &cl->format, fakeFrameBuffer + (y * pVNC->width * cl->format.bitsPerPixel / 8),
|
||
|
+ pVNC->paddedWidthInBytes, pVNC->width, h, 0, y);
|
||
|
+
|
||
|
+ /* Call the inner part */
|
||
|
+
|
||
|
+ return SendRectEncodingTight(cl, x, y, w, h);
|
||
|
+}
|
||
|
+
|
||
|
+static Bool
|
||
|
+SendRectEncodingTight(rfbClientPtr cl,
|
||
|
+ int x, int y, int w, int h)
|
||
|
+{
|
||
|
+ VNCSCREENPTR(cl->pScreen);
|
||
|
int nMaxRows;
|
||
|
CARD32 colorValue;
|
||
|
int dx, dy, dw, dh;
|
||
|
@@ -247,7 +269,7 @@ rfbSendRectEncodingTight(rfbClientPtr cl,
|
||
|
nMaxWidth = (w > maxRectWidth) ? maxRectWidth : w;
|
||
|
nMaxRows = maxRectSize / nMaxWidth;
|
||
|
}
|
||
|
-
|
||
|
+
|
||
|
/* Try to find large solid-color areas and send them separately. */
|
||
|
|
||
|
for (dy = y; dy < y + h; dy += MAX_SPLIT_TILE_SIZE) {
|
||
|
@@ -269,11 +291,11 @@ rfbSendRectEncodingTight(rfbClientPtr cl,
|
||
|
dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w) ?
|
||
|
MAX_SPLIT_TILE_SIZE : (x + w - dx);
|
||
|
|
||
|
- if (CheckSolidTile(cl->pScreen, dx, dy, dw, dh, &colorValue, FALSE)) {
|
||
|
+ if (CheckSolidTile(cl, dx, dy, dw, dh, &colorValue, FALSE)) {
|
||
|
|
||
|
/* Get dimensions of solid-color area. */
|
||
|
|
||
|
- FindBestSolidArea(cl->pScreen, dx, dy, w - (dx - x), h - (dy - y),
|
||
|
+ FindBestSolidArea(cl, dx, dy, w - (dx - x), h - (dy - y),
|
||
|
colorValue, &w_best, &h_best);
|
||
|
|
||
|
/* Make sure a solid rectangle is large enough
|
||
|
@@ -286,7 +308,7 @@ rfbSendRectEncodingTight(rfbClientPtr cl,
|
||
|
/* Try to extend solid rectangle to maximum size. */
|
||
|
|
||
|
x_best = dx; y_best = dy;
|
||
|
- ExtendSolidArea(cl->pScreen, x, y, w, h, colorValue,
|
||
|
+ ExtendSolidArea(cl, x, y, w, h, colorValue,
|
||
|
&x_best, &y_best, &w_best, &h_best);
|
||
|
|
||
|
/* Send rectangles at top and left to solid-color area. */
|
||
|
@@ -295,7 +317,7 @@ rfbSendRectEncodingTight(rfbClientPtr cl,
|
||
|
!SendRectSimple(cl, x, y, w, y_best-y) )
|
||
|
return FALSE;
|
||
|
if ( x_best != x &&
|
||
|
- !rfbSendRectEncodingTight(cl, x, y_best,
|
||
|
+ !SendRectEncodingTight(cl, x, y_best,
|
||
|
x_best-x, h_best) )
|
||
|
return FALSE;
|
||
|
|
||
|
@@ -316,11 +338,11 @@ rfbSendRectEncodingTight(rfbClientPtr cl,
|
||
|
/* Send remaining rectangles (at right and bottom). */
|
||
|
|
||
|
if ( x_best + w_best != x + w &&
|
||
|
- !rfbSendRectEncodingTight(cl, x_best+w_best, y_best,
|
||
|
+ !SendRectEncodingTight(cl, x_best+w_best, y_best,
|
||
|
w-(x_best-x)-w_best, h_best) )
|
||
|
return FALSE;
|
||
|
if ( y_best + h_best != y + h &&
|
||
|
- !rfbSendRectEncodingTight(cl, x, y_best+h_best,
|
||
|
+ !SendRectEncodingTight(cl, x, y_best+h_best,
|
||
|
w, h-(y_best-y)-h_best) )
|
||
|
return FALSE;
|
||
|
|
||
|
@@ -339,7 +361,7 @@ rfbSendRectEncodingTight(rfbClientPtr cl,
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-FindBestSolidArea(ScreenPtr pScreen,
|
||
|
+FindBestSolidArea(rfbClientPtr cl,
|
||
|
int x, int y, int w, int h,
|
||
|
CARD32 colorValue,
|
||
|
int *w_ptr, int *h_ptr)
|
||
|
@@ -357,13 +379,13 @@ FindBestSolidArea(ScreenPtr pScreen,
|
||
|
dw = (w_prev > MAX_SPLIT_TILE_SIZE) ?
|
||
|
MAX_SPLIT_TILE_SIZE : w_prev;
|
||
|
|
||
|
- if (!CheckSolidTile(pScreen, x, dy, dw, dh, &colorValue, TRUE))
|
||
|
+ if (!CheckSolidTile(cl, x, dy, dw, dh, &colorValue, TRUE))
|
||
|
break;
|
||
|
|
||
|
for (dx = x + dw; dx < x + w_prev;) {
|
||
|
dw = (dx + MAX_SPLIT_TILE_SIZE <= x + w_prev) ?
|
||
|
MAX_SPLIT_TILE_SIZE : (x + w_prev - dx);
|
||
|
- if (!CheckSolidTile(pScreen, dx, dy, dw, dh, &colorValue, TRUE))
|
||
|
+ if (!CheckSolidTile(cl, dx, dy, dw, dh, &colorValue, TRUE))
|
||
|
break;
|
||
|
dx += dw;
|
||
|
}
|
||
|
@@ -380,7 +402,7 @@ FindBestSolidArea(ScreenPtr pScreen,
|
||
|
}
|
||
|
|
||
|
static void
|
||
|
-ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
+ExtendSolidArea(rfbClientPtr cl, int x, int y, int w, int h,
|
||
|
CARD32 colorValue,
|
||
|
int *x_ptr, int *y_ptr, int *w_ptr, int *h_ptr)
|
||
|
{
|
||
|
@@ -388,7 +410,7 @@ ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
|
||
|
/* Try to extend the area upwards. */
|
||
|
for ( cy = *y_ptr - 1;
|
||
|
- cy >= y && CheckSolidTile(pScreen, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE);
|
||
|
+ cy >= y && CheckSolidTile(cl, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE);
|
||
|
cy-- );
|
||
|
*h_ptr += *y_ptr - (cy + 1);
|
||
|
*y_ptr = cy + 1;
|
||
|
@@ -396,13 +418,13 @@ ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
/* ... downwards. */
|
||
|
for ( cy = *y_ptr + *h_ptr;
|
||
|
cy < y + h &&
|
||
|
- CheckSolidTile(pScreen, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE);
|
||
|
+ CheckSolidTile(cl, *x_ptr, cy, *w_ptr, 1, &colorValue, TRUE);
|
||
|
cy++ );
|
||
|
*h_ptr += cy - (*y_ptr + *h_ptr);
|
||
|
|
||
|
/* ... to the left. */
|
||
|
for ( cx = *x_ptr - 1;
|
||
|
- cx >= x && CheckSolidTile(pScreen, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE);
|
||
|
+ cx >= x && CheckSolidTile(cl, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE);
|
||
|
cx-- );
|
||
|
*w_ptr += *x_ptr - (cx + 1);
|
||
|
*x_ptr = cx + 1;
|
||
|
@@ -410,7 +432,7 @@ ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
/* ... to the right. */
|
||
|
for ( cx = *x_ptr + *w_ptr;
|
||
|
cx < x + w &&
|
||
|
- CheckSolidTile(pScreen, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE);
|
||
|
+ CheckSolidTile(cl, cx, *y_ptr, 1, *h_ptr, &colorValue, TRUE);
|
||
|
cx++ );
|
||
|
*w_ptr += cx - (*x_ptr + *w_ptr);
|
||
|
}
|
||
|
@@ -423,11 +445,12 @@ ExtendSolidArea(ScreenPtr pScreen, int x, int y, int w, int h,
|
||
|
*/
|
||
|
|
||
|
static Bool
|
||
|
-CheckSolidTile(ScreenPtr pScreen, int x, int y, int w, int h, CARD32 *colorPtr,
|
||
|
+CheckSolidTile(rfbClientPtr cl, int x, int y, int w, int h, CARD32 *colorPtr,
|
||
|
Bool needSameColor)
|
||
|
{
|
||
|
- VNCSCREENPTR(pScreen);
|
||
|
- switch(pVNC->rfbServerFormat.bitsPerPixel) {
|
||
|
+ ScreenPtr pScreen = cl->pScreen;
|
||
|
+
|
||
|
+ switch(cl->format.bitsPerPixel) {
|
||
|
case 32:
|
||
|
return CheckSolidTile32(pScreen, x, y, w, h, colorPtr, needSameColor);
|
||
|
case 16:
|
||
|
@@ -449,7 +472,7 @@ static Bool \
|
||
|
int dx, dy; \
|
||
|
\
|
||
|
fbptr = (CARD##bpp *) \
|
||
|
- &pVNC->pfbMemory[y * pVNC->paddedWidthInBytes + x * (bpp/8)]; \
|
||
|
+ &fakeFrameBuffer[(y * pVNC->width + x) * (bpp/8)]; \
|
||
|
\
|
||
|
colorValue = *fbptr; \
|
||
|
if (needSameColor && (CARD32)colorValue != *colorPtr) \
|
||
|
@@ -460,7 +483,7 @@ static Bool \
|
||
|
if (colorValue != fbptr[dx]) \
|
||
|
return FALSE; \
|
||
|
} \
|
||
|
- fbptr = (CARD##bpp *)((CARD8 *)fbptr + pVNC->paddedWidthInBytes); \
|
||
|
+ fbptr = (CARD##bpp *)((CARD8 *)fbptr + pVNC->width * (bpp/8)); \
|
||
|
} \
|
||
|
\
|
||
|
*colorPtr = (CARD32)colorValue; \
|
||
|
diff --git a/hw/vnc/vncext.c b/hw/vnc/vncext.c
|
||
|
index ea913b7..534f3f5 100644
|
||
|
--- a/hw/vnc/vncext.c
|
||
|
+++ b/hw/vnc/vncext.c
|
||
|
@@ -702,15 +702,7 @@ CreateResourceTypes(void)
|
||
|
|
||
|
static unsigned long vncExtGeneration = 0;
|
||
|
#if XFREE86VNC
|
||
|
-extern Bool VNCInit(ScreenPtr pScreen, unsigned char *FBStart);
|
||
|
-
|
||
|
-/* copied from miscrinit.c */
|
||
|
-typedef struct
|
||
|
-{
|
||
|
- pointer pbits; /* pointer to framebuffer */
|
||
|
- int width; /* delta to add to a framebuffer addr to move one row down */
|
||
|
-} miScreenInitParmsRec, *miScreenInitParmsPtr;
|
||
|
-
|
||
|
+extern Bool VNCInit(ScreenPtr pScreen);
|
||
|
|
||
|
static Bool
|
||
|
vncCreateScreenResources(ScreenPtr pScreen)
|
||
|
@@ -719,9 +711,6 @@ vncCreateScreenResources(ScreenPtr pScreen)
|
||
|
CreateScreenResourcesProcPtr CreateScreenResources =
|
||
|
(CreateScreenResourcesProcPtr)
|
||
|
dixLookupPrivate(&pScreen->devPrivates, vncCreateScreenResourcesKey);
|
||
|
- miScreenInitParmsPtr pScrInitParms;
|
||
|
-
|
||
|
- pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate;
|
||
|
|
||
|
if ( pScreen->CreateScreenResources != vncCreateScreenResources ) {
|
||
|
/* Can't find hook we are hung on */
|
||
|
@@ -732,9 +721,6 @@ vncCreateScreenResources(ScreenPtr pScreen)
|
||
|
(void *) pScreen->CreateScreenResources );
|
||
|
}
|
||
|
|
||
|
- /* Now do our stuff */
|
||
|
- VNCInit(pScreen, pScrInitParms->pbits);
|
||
|
-
|
||
|
/* Unhook this function ... */
|
||
|
pScreen->CreateScreenResources = CreateScreenResources;
|
||
|
dixSetPrivate(&pScreen->devPrivates, vncCreateScreenResourcesKey, NULL);
|
||
|
@@ -744,6 +730,9 @@ vncCreateScreenResources(ScreenPtr pScreen)
|
||
|
ret = (*pScreen->CreateScreenResources)(pScreen);
|
||
|
}
|
||
|
|
||
|
+ /* Now do our stuff */
|
||
|
+ VNCInit(pScreen);
|
||
|
+
|
||
|
#ifdef DEBUG
|
||
|
ErrorF("vncCreateScreenResources() returns %d\n", ret);
|
||
|
#endif
|
||
|
diff --git a/hw/xfree86/vnc/vncInit.c b/hw/xfree86/vnc/vncInit.c
|
||
|
index 4a124fb..8b2fa5f 100644
|
||
|
--- a/hw/xfree86/vnc/vncInit.c
|
||
|
+++ b/hw/xfree86/vnc/vncInit.c
|
||
|
@@ -49,7 +49,7 @@ extern void VncExtensionInit(void);
|
||
|
|
||
|
extern void vncInitMouse(void);
|
||
|
extern void vncInitKeyb(void);
|
||
|
-Bool VNCInit(ScreenPtr pScreen, unsigned char *FBStart);
|
||
|
+Bool VNCInit(ScreenPtr pScreen);
|
||
|
|
||
|
#ifndef XFree86LOADER
|
||
|
static unsigned long VNCGeneration = 0;
|
||
|
@@ -151,7 +151,7 @@ void rfbLogPerror(char *str)
|
||
|
* Called by vncCreateScreenResources()
|
||
|
*/
|
||
|
Bool
|
||
|
-VNCInit(ScreenPtr pScreen, unsigned char *FBStart)
|
||
|
+VNCInit(ScreenPtr pScreen)
|
||
|
{
|
||
|
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||
|
VisualPtr visual;
|
||
|
@@ -164,9 +164,6 @@ VNCInit(ScreenPtr pScreen, unsigned char *FBStart)
|
||
|
PictureScreenPtr ps;
|
||
|
#endif
|
||
|
|
||
|
- if (!FBStart)
|
||
|
- return FALSE;
|
||
|
-
|
||
|
#ifndef XFree86LOADER
|
||
|
if (VNCGeneration != serverGeneration) {
|
||
|
VncExtensionInit();
|
||
|
@@ -287,9 +284,7 @@ VNCInit(ScreenPtr pScreen, unsigned char *FBStart)
|
||
|
pScreenPriv->depth = pScrn->depth;
|
||
|
pScreenPriv->paddedWidthInBytes = PixmapBytePad(pScrn->displayWidth, pScrn->depth);
|
||
|
pScreenPriv->bitsPerPixel = rfbBitsPerPixel(pScrn->depth);
|
||
|
- pScreenPriv->pfbMemory = FBStart;
|
||
|
- pScreenPriv->oldpfbMemory = FBStart;
|
||
|
-
|
||
|
+
|
||
|
pScreenPriv->cursorIsDrawn = TRUE;
|
||
|
pScreenPriv->dontSendFramebufferUpdate = FALSE;
|
||
|
|
||
|
diff --git a/hw/xfree86/vnc/vncint.h b/hw/xfree86/vnc/vncint.h
|
||
|
index 18a3630..9e4a36f 100644
|
||
|
--- a/hw/xfree86/vnc/vncint.h
|
||
|
+++ b/hw/xfree86/vnc/vncint.h
|
||
|
@@ -44,13 +44,11 @@ typedef struct {
|
||
|
size_t buf_filled;
|
||
|
int maxFd;
|
||
|
fd_set allFds;
|
||
|
- unsigned char * oldpfbMemory;
|
||
|
Bool rfbAlwaysShared;
|
||
|
Bool rfbNeverShared;
|
||
|
Bool rfbDontDisconnect;
|
||
|
Bool rfbUserAccept;
|
||
|
Bool rfbViewOnly;
|
||
|
- unsigned char * pfbMemory;
|
||
|
int paddedWidthInBytes;
|
||
|
ColormapPtr rfbInstalledColormap;
|
||
|
ColormapPtr savedColormap;
|
||
|
--
|
||
|
1.7.3.4
|
||
|
|