vnc: use the new generic bitmap functions

Switch to bitmap.h and bitops.h instead of redefining our own bitmap
helpers.

Signed-off-by: Corentin Chary <corentincj@iksaif.net>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Corentin Chary 2011-02-04 09:06:05 +01:00 committed by Anthony Liguori
parent e0e53b2f1b
commit bc2429b917
2 changed files with 25 additions and 73 deletions

View File

@ -41,13 +41,6 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
#include "vnc_keysym.h"
#include "d3des.h"
#define count_bits(c, v) { \
for (c = 0; v; v >>= 1) \
{ \
c += v & 1; \
} \
}
static VncDisplay *vnc_display; /* needed for info vnc */
static DisplayChangeListener *dcl;
@ -378,47 +371,6 @@ static void framebuffer_update_request(VncState *vs, int incremental,
static void vnc_refresh(void *opaque);
static int vnc_refresh_server_surface(VncDisplay *vd);
static inline void vnc_set_bit(uint32_t *d, int k)
{
d[k >> 5] |= 1 << (k & 0x1f);
}
static inline void vnc_clear_bit(uint32_t *d, int k)
{
d[k >> 5] &= ~(1 << (k & 0x1f));
}
static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
{
int j;
j = 0;
while (n >= 32) {
d[j++] = -1;
n -= 32;
}
if (n > 0)
d[j++] = (1 << n) - 1;
while (j < nb_words)
d[j++] = 0;
}
static inline int vnc_get_bit(const uint32_t *d, int k)
{
return (d[k >> 5] >> (k & 0x1f)) & 1;
}
static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
int nb_words)
{
int i;
for(i = 0; i < nb_words; i++) {
if ((d1[i] & d2[i]) != 0)
return 1;
}
return 0;
}
static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
{
int i;
@ -441,7 +393,7 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
for (; y < h; y++)
for (i = 0; i < w; i += 16)
vnc_set_bit(s->dirty[y], (x + i) / 16);
set_bit((x + i) / 16, s->dirty[y]);
}
void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
@ -780,7 +732,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
memmove(dst_row, src_row, cmp_bytes);
QTAILQ_FOREACH(vs, &vd->clients, next) {
if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
vnc_set_bit(vs->dirty[y], ((x + dst_x) / 16));
set_bit(((x + dst_x) / 16), vs->dirty[y]);
}
}
}
@ -850,10 +802,12 @@ static int find_and_clear_dirty_height(struct VncState *vs,
for (h = 1; h < (vd->server->height - y); h++) {
int tmp_x;
if (!vnc_get_bit(vs->dirty[y + h], last_x))
if (!test_bit(last_x, vs->dirty[y + h])) {
break;
for (tmp_x = last_x; tmp_x < x; tmp_x++)
vnc_clear_bit(vs->dirty[y + h], tmp_x);
}
for (tmp_x = last_x; tmp_x < x; tmp_x++) {
clear_bit(tmp_x, vs->dirty[y + h]);
}
}
return h;
@ -905,11 +859,10 @@ static int vnc_update_client(VncState *vs, int has_dirty)
int x;
int last_x = -1;
for (x = 0; x < width / 16; x++) {
if (vnc_get_bit(vs->dirty[y], x)) {
if (test_and_clear_bit(x, vs->dirty[y])) {
if (last_x == -1) {
last_x = x;
}
vnc_clear_bit(vs->dirty[y], x);
} else {
if (last_x != -1) {
int h = find_and_clear_dirty_height(vs, y, last_x, x);
@ -1702,8 +1655,7 @@ static void framebuffer_update_request(VncState *vs, int incremental,
if (!incremental) {
vs->force_update = 1;
for (i = 0; i < h; i++) {
vnc_set_bits(vs->dirty[y_position + i],
(ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
bitmap_set(vs->dirty[y_position + i], x_position / 16, w / 16);
}
}
}
@ -1842,15 +1794,15 @@ static void set_pixel_format(VncState *vs,
vs->clientds = *(vs->vd->guest.ds);
vs->clientds.pf.rmax = red_max;
count_bits(vs->clientds.pf.rbits, red_max);
vs->clientds.pf.rbits = hweight_long(red_max);
vs->clientds.pf.rshift = red_shift;
vs->clientds.pf.rmask = red_max << red_shift;
vs->clientds.pf.gmax = green_max;
count_bits(vs->clientds.pf.gbits, green_max);
vs->clientds.pf.gbits = hweight_long(green_max);
vs->clientds.pf.gshift = green_shift;
vs->clientds.pf.gmask = green_max << green_shift;
vs->clientds.pf.bmax = blue_max;
count_bits(vs->clientds.pf.bbits, blue_max);
vs->clientds.pf.bbits = hweight_long(blue_max);
vs->clientds.pf.bshift = blue_shift;
vs->clientds.pf.bmask = blue_max << blue_shift;
vs->clientds.pf.bits_per_pixel = bits_per_pixel;
@ -2315,7 +2267,7 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
x = x / VNC_STAT_RECT * VNC_STAT_RECT;
QTAILQ_FOREACH(vs, &vd->clients, next) {
int j, i;
int j;
/* kernel send buffers are full -> refresh later */
if (vs->output.offset) {
@ -2328,9 +2280,7 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
vs->lossy_rect[sty][stx] = 0;
for (j = 0; j < VNC_STAT_RECT; ++j) {
for (i = x / 16; i < VNC_STAT_RECT / 16 + x / 16; ++i) {
vnc_set_bit(vs->dirty[y + j], i);
}
bitmap_set(vs->dirty[y + j], x / 16, VNC_STAT_RECT / 16);
}
has_dirty++;
}
@ -2433,7 +2383,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
uint8_t *guest_row;
uint8_t *server_row;
int cmp_bytes;
uint32_t width_mask[VNC_DIRTY_WORDS];
unsigned long width_mask[VNC_DIRTY_WORDS];
VncState *vs;
int has_dirty = 0;
@ -2447,12 +2397,14 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
* Check and copy modified bits from guest to server surface.
* Update server dirty map.
*/
vnc_set_bits(width_mask, (ds_get_width(vd->ds) / 16), VNC_DIRTY_WORDS);
bitmap_set(width_mask, 0, (ds_get_width(vd->ds) / 16));
bitmap_clear(width_mask, (ds_get_width(vd->ds) / 16),
VNC_DIRTY_WORDS * BITS_PER_LONG);
cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
guest_row = vd->guest.ds->data;
server_row = vd->server->data;
for (y = 0; y < vd->guest.ds->height; y++) {
if (vnc_and_bits(vd->guest.dirty[y], width_mask, VNC_DIRTY_WORDS)) {
if (bitmap_intersects(vd->guest.dirty[y], width_mask, VNC_DIRTY_WORDS)) {
int x;
uint8_t *guest_ptr;
uint8_t *server_ptr;
@ -2462,15 +2414,14 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
for (x = 0; x < vd->guest.ds->width;
x += 16, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
if (!vnc_get_bit(vd->guest.dirty[y], (x / 16)))
if (!test_and_clear_bit((x / 16), vd->guest.dirty[y]))
continue;
vnc_clear_bit(vd->guest.dirty[y], (x / 16));
if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0)
continue;
memcpy(server_ptr, guest_ptr, cmp_bytes);
vnc_rect_updated(vd, x, y, &tv);
QTAILQ_FOREACH(vs, &vd->clients, next) {
vnc_set_bit(vs->dirty[y], (x / 16));
set_bit((x / 16), vs->dirty[y]);
}
has_dirty++;
}

View File

@ -35,6 +35,7 @@
#include "console.h"
#include "monitor.h"
#include "audio/audio.h"
#include "bitmap.h"
#include <zlib.h>
#include <stdbool.h>
@ -80,7 +81,7 @@ typedef void VncSendHextileTile(VncState *vs,
#define VNC_MAX_WIDTH 2560
#define VNC_MAX_HEIGHT 2048
#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * BITS_PER_LONG))
#define VNC_STAT_RECT 64
#define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
@ -113,7 +114,7 @@ typedef struct VncRectStat VncRectStat;
struct VncSurface
{
struct timeval last_freq_check;
uint32_t dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
DisplaySurface *ds;
};
@ -232,7 +233,7 @@ struct VncState
int csock;
DisplayState *ds;
uint32_t dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
* vnc-jobs-async.c */