vnc: return the number of rectangles

Some encodings like tight supports tiling (spliting in
multiple sub-rectangles). So we needed a way to tell
vnc_update_client() how much rectangles are in the buffer.

zlib, raw and hextile always send a full rectangle.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Corentin Chary 2010-05-19 09:24:09 +02:00 committed by Anthony Liguori
parent 161c4f20bf
commit a885211eed
4 changed files with 26 additions and 16 deletions

View file

@ -62,8 +62,8 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
#undef BPP #undef BPP
#undef GENERIC #undef GENERIC
void vnc_hextile_send_framebuffer_update(VncState *vs, int x, int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
int y, int w, int h) int y, int w, int h)
{ {
int i, j; int i, j;
int has_fg, has_bg; int has_fg, has_bg;
@ -83,6 +83,7 @@ void vnc_hextile_send_framebuffer_update(VncState *vs, int x,
free(last_fg); free(last_fg);
free(last_bg); free(last_bg);
return 1;
} }
void vnc_hextile_set_pixel_conversion(VncState *vs, int generic) void vnc_hextile_set_pixel_conversion(VncState *vs, int generic)

View file

@ -116,7 +116,7 @@ static int vnc_zlib_stop(VncState *vs)
return zstream->total_out - previous_out; return zstream->total_out - previous_out;
} }
void vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
{ {
int old_offset, new_offset, bytes_written; int old_offset, new_offset, bytes_written;
@ -132,13 +132,15 @@ void vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
bytes_written = vnc_zlib_stop(vs); bytes_written = vnc_zlib_stop(vs);
if (bytes_written == -1) if (bytes_written == -1)
return; return 0;
// hack in the size // hack in the size
new_offset = vs->output.offset; new_offset = vs->output.offset;
vs->output.offset = old_offset; vs->output.offset = old_offset;
vnc_write_u32(vs, bytes_written); vnc_write_u32(vs, bytes_written);
vs->output.offset = new_offset; vs->output.offset = new_offset;
return 1;
} }
void vnc_zlib_clear(VncState *vs) void vnc_zlib_clear(VncState *vs)

25
vnc.c
View file

@ -652,7 +652,7 @@ static void vnc_write_pixels_generic(VncState *vs, struct PixelFormat *pf,
} }
} }
void vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h) int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
{ {
int i; int i;
uint8_t *row; uint8_t *row;
@ -663,23 +663,27 @@ void vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
vs->write_pixels(vs, &vd->server->pf, row, w * ds_get_bytes_per_pixel(vs->ds)); vs->write_pixels(vs, &vd->server->pf, row, w * ds_get_bytes_per_pixel(vs->ds));
row += ds_get_linesize(vs->ds); row += ds_get_linesize(vs->ds);
} }
return 1;
} }
static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) static int send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
{ {
int n = 0;
switch(vs->vnc_encoding) { switch(vs->vnc_encoding) {
case VNC_ENCODING_ZLIB: case VNC_ENCODING_ZLIB:
vnc_zlib_send_framebuffer_update(vs, x, y, w, h); n = vnc_zlib_send_framebuffer_update(vs, x, y, w, h);
break; break;
case VNC_ENCODING_HEXTILE: case VNC_ENCODING_HEXTILE:
vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE); vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_HEXTILE);
vnc_hextile_send_framebuffer_update(vs, x, y, w, h); n = vnc_hextile_send_framebuffer_update(vs, x, y, w, h);
break; break;
default: default:
vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW); vnc_framebuffer_update(vs, x, y, w, h, VNC_ENCODING_RAW);
vnc_raw_send_framebuffer_update(vs, x, y, w, h); n = vnc_raw_send_framebuffer_update(vs, x, y, w, h);
break; break;
} }
return n;
} }
static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h) static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
@ -834,6 +838,7 @@ static int vnc_update_client(VncState *vs, int has_dirty)
int y; int y;
int n_rectangles; int n_rectangles;
int saved_offset; int saved_offset;
int n;
if (vs->output.offset && !vs->audio_cap && !vs->force_update) if (vs->output.offset && !vs->audio_cap && !vs->force_update)
/* kernel send buffers are full -> drop frames to throttle */ /* kernel send buffers are full -> drop frames to throttle */
@ -866,16 +871,18 @@ static int vnc_update_client(VncState *vs, int has_dirty)
} else { } else {
if (last_x != -1) { if (last_x != -1) {
int h = find_and_clear_dirty_height(vs, y, last_x, x); int h = find_and_clear_dirty_height(vs, y, last_x, x);
send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h); n = send_framebuffer_update(vs, last_x * 16, y,
n_rectangles++; (x - last_x) * 16, h);
n_rectangles += n;
} }
last_x = -1; last_x = -1;
} }
} }
if (last_x != -1) { if (last_x != -1) {
int h = find_and_clear_dirty_height(vs, y, last_x, x); int h = find_and_clear_dirty_height(vs, y, last_x, x);
send_framebuffer_update(vs, last_x * 16, y, (x - last_x) * 16, h); n = send_framebuffer_update(vs, last_x * 16, y,
n_rectangles++; (x - last_x) * 16, h);
n_rectangles += n;
} }
} }
vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF; vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;

6
vnc.h
View file

@ -398,13 +398,13 @@ void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v); void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v);
/* Encodings */ /* Encodings */
void vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h); int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
void vnc_hextile_send_framebuffer_update(VncState *vs, int x, int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
int y, int w, int h); int y, int w, int h);
void vnc_hextile_set_pixel_conversion(VncState *vs, int generic); void vnc_hextile_set_pixel_conversion(VncState *vs, int generic);
void vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h); int vnc_zlib_send_framebuffer_update(VncState *vs, int x, int y, int w, int h);
void vnc_zlib_clear(VncState *vs); void vnc_zlib_clear(VncState *vs);
#endif /* __QEMU_VNC_H */ #endif /* __QEMU_VNC_H */