Skip to content

Commit

Permalink
pixman/vnc: use pixman images in vnc.
Browse files Browse the repository at this point in the history
The vnc code uses *three* DisplaySurfaces:

First is the surface of the actual QemuConsole, usually the guest
screen, but could also be a text console (monitor/serial reachable via
Ctrl-Alt-<nr> keys).  This is left as-is.

Second is the current server's view of the screen content.  The vnc code
uses this to figure which parts of the guest screen did _really_ change
to reduce the amount of updates sent to the vnc clients.  It is also
used as data source when sending out the updates to the clients.  This
surface gets replaced by a pixman image.  The format changes too,
instead of using the guest screen format we'll use fixed 32bit rgb
framebuffer and convert the pixels on the fly when comparing and
updating the server framebuffer.

Third surface carries the format expected by the vnc client.  That isn't
used to store image data.  This surface is switched to PixelFormat and a
boolean for bigendian byte order.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
  • Loading branch information
kraxel committed Nov 1, 2012
1 parent b12f32c commit 9f64916
Show file tree
Hide file tree
Showing 7 changed files with 259 additions and 228 deletions.
23 changes: 11 additions & 12 deletions ui/vnc-enc-hextile-template.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
int *has_bg, int *has_fg)
{
VncDisplay *vd = vs->vd;
uint8_t *row = vd->server->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
uint8_t *row = vnc_server_fb_ptr(vd, x, y);
pixel_t *irow = (pixel_t *)row;
int j, i;
pixel_t *last_bg = (pixel_t *)last_bg_;
Expand All @@ -25,7 +25,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
int bg_count = 0;
int fg_count = 0;
int flags = 0;
uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16];
uint8_t data[(vs->client_pf.bytes_per_pixel + 2) * 16 * 16];
int n_data = 0;
int n_subtiles = 0;

Expand Down Expand Up @@ -58,7 +58,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
}
if (n_colors > 2)
break;
irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
}

if (n_colors > 1 && fg_count > bg_count) {
Expand Down Expand Up @@ -106,7 +106,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
n_data += 2;
n_subtiles++;
}
irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
}
break;
case 3:
Expand All @@ -133,7 +133,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
has_color = 0;
#ifdef GENERIC
vnc_convert_pixel(vs, data + n_data, color);
n_data += vs->clientds.pf.bytes_per_pixel;
n_data += vs->client_pf.bytes_per_pixel;
#else
memcpy(data + n_data, &color, sizeof(color));
n_data += sizeof(pixel_t);
Expand All @@ -153,7 +153,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
if (has_color) {
#ifdef GENERIC
vnc_convert_pixel(vs, data + n_data, color);
n_data += vs->clientds.pf.bytes_per_pixel;
n_data += vs->client_pf.bytes_per_pixel;
#else
memcpy(data + n_data, &color, sizeof(color));
n_data += sizeof(pixel_t);
Expand All @@ -162,7 +162,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
n_data += 2;
n_subtiles++;
}
irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
}

/* A SubrectsColoured subtile invalidates the foreground color */
Expand Down Expand Up @@ -190,18 +190,17 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
vnc_write_u8(vs, flags);
if (n_colors < 4) {
if (flags & 0x02)
vs->write_pixels(vs, &vd->server->pf, last_bg, sizeof(pixel_t));
vs->write_pixels(vs, last_bg, sizeof(pixel_t));
if (flags & 0x04)
vs->write_pixels(vs, &vd->server->pf, last_fg, sizeof(pixel_t));
vs->write_pixels(vs, last_fg, sizeof(pixel_t));
if (n_subtiles) {
vnc_write_u8(vs, n_subtiles);
vnc_write(vs, data, n_data);
}
} else {
for (j = 0; j < h; j++) {
vs->write_pixels(vs, &vd->server->pf, row,
w * ds_get_bytes_per_pixel(vs->ds));
row += ds_get_linesize(vs->ds);
vs->write_pixels(vs, row, w * 4);
row += vnc_server_fb_stride(vd);
}
}
}
Expand Down
45 changes: 22 additions & 23 deletions ui/vnc-enc-hextile.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,9 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
int i, j;
int has_fg, has_bg;
uint8_t *last_fg, *last_bg;
VncDisplay *vd = vs->vd;

last_fg = (uint8_t *) g_malloc(vd->server->pf.bytes_per_pixel);
last_bg = (uint8_t *) g_malloc(vd->server->pf.bytes_per_pixel);
last_fg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES);
last_bg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES);
has_fg = has_bg = 0;
for (j = y; j < (y + h); j += 16) {
for (i = x; i < (x + w); i += 16) {
Expand All @@ -89,28 +88,28 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
void vnc_hextile_set_pixel_conversion(VncState *vs, int generic)
{
if (!generic) {
switch (vs->ds->surface->pf.bits_per_pixel) {
case 8:
vs->hextile.send_tile = send_hextile_tile_8;
break;
case 16:
vs->hextile.send_tile = send_hextile_tile_16;
break;
case 32:
vs->hextile.send_tile = send_hextile_tile_32;
break;
switch (VNC_SERVER_FB_BITS) {
case 8:
vs->hextile.send_tile = send_hextile_tile_8;
break;
case 16:
vs->hextile.send_tile = send_hextile_tile_16;
break;
case 32:
vs->hextile.send_tile = send_hextile_tile_32;
break;
}
} else {
switch (vs->ds->surface->pf.bits_per_pixel) {
case 8:
vs->hextile.send_tile = send_hextile_tile_generic_8;
break;
case 16:
vs->hextile.send_tile = send_hextile_tile_generic_16;
break;
case 32:
vs->hextile.send_tile = send_hextile_tile_generic_32;
break;
switch (VNC_SERVER_FB_BITS) {
case 8:
vs->hextile.send_tile = send_hextile_tile_generic_8;
break;
case 16:
vs->hextile.send_tile = send_hextile_tile_generic_16;
break;
case 32:
vs->hextile.send_tile = send_hextile_tile_generic_32;
break;
}
}
}
Loading

0 comments on commit 9f64916

Please sign in to comment.