Commit a885211e authored by Corentin Chary's avatar Corentin Chary Committed by Anthony Liguori

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: default avatarCorentin Chary <corentincj@iksaif.net>
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
parent 161c4f20
......@@ -62,8 +62,8 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
#undef BPP
#undef GENERIC
void vnc_hextile_send_framebuffer_update(VncState *vs, int x,
int y, int w, int h)
int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
int y, int w, int h)
{
int i, j;
int has_fg, has_bg;
......@@ -83,6 +83,7 @@ void vnc_hextile_send_framebuffer_update(VncState *vs, int x,
free(last_fg);
free(last_bg);
return 1;
}
void vnc_hextile_set_pixel_conversion(VncState *vs, int generic)
......
......@@ -116,7 +116,7 @@ static int vnc_zlib_stop(VncState *vs)
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;
......@@ -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);
if (bytes_written == -1)
return;
return 0;
// hack in the size
new_offset = vs->output.offset;
vs->output.offset = old_offset;
vnc_write_u32(vs, bytes_written);
vs->output.offset = new_offset;
return 1;
}
void vnc_zlib_clear(VncState *vs)
......
......@@ -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;
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));
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) {
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;
case 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;
default:
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;
}
return n;
}
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 n_rectangles;
int saved_offset;
int n;
if (vs->output.offset && !vs->audio_cap && !vs->force_update)
/* kernel send buffers are full -> drop frames to throttle */
......@@ -866,16 +871,18 @@ static int vnc_update_client(VncState *vs, int has_dirty)
} else {
if (last_x != -1) {
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_rectangles++;
n = send_framebuffer_update(vs, last_x * 16, y,
(x - last_x) * 16, h);
n_rectangles += n;
}
last_x = -1;
}
}
if (last_x != -1) {
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_rectangles++;
n = send_framebuffer_update(vs, last_x * 16, y,
(x - last_x) * 16, h);
n_rectangles += n;
}
}
vs->output.buffer[saved_offset] = (n_rectangles >> 8) & 0xFF;
......
......@@ -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);
/* 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);
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);
#endif /* __QEMU_VNC_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment