提交 bc2429b9 编写于 作者: C Corentin Chary 提交者: Anthony Liguori

vnc: use the new generic bitmap functions

Switch to bitmap.h and bitops.h instead of redefining our own bitmap
helpers.
Signed-off-by: NCorentin Chary <corentincj@iksaif.net>
Signed-off-by: NAnthony Liguori <aliguori@us.ibm.com>
上级 e0e53b2f
...@@ -41,13 +41,6 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 }; ...@@ -41,13 +41,6 @@ static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
#include "vnc_keysym.h" #include "vnc_keysym.h"
#include "d3des.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 VncDisplay *vnc_display; /* needed for info vnc */
static DisplayChangeListener *dcl; static DisplayChangeListener *dcl;
...@@ -378,47 +371,6 @@ static void framebuffer_update_request(VncState *vs, int incremental, ...@@ -378,47 +371,6 @@ static void framebuffer_update_request(VncState *vs, int incremental,
static void vnc_refresh(void *opaque); static void vnc_refresh(void *opaque);
static int vnc_refresh_server_surface(VncDisplay *vd); 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) static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
{ {
int i; int i;
...@@ -441,7 +393,7 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) ...@@ -441,7 +393,7 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
for (; y < h; y++) for (; y < h; y++)
for (i = 0; i < w; i += 16) 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, 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 ...@@ -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); memmove(dst_row, src_row, cmp_bytes);
QTAILQ_FOREACH(vs, &vd->clients, next) { QTAILQ_FOREACH(vs, &vd->clients, next) {
if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) { 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, ...@@ -850,10 +802,12 @@ static int find_and_clear_dirty_height(struct VncState *vs,
for (h = 1; h < (vd->server->height - y); h++) { for (h = 1; h < (vd->server->height - y); h++) {
int tmp_x; int tmp_x;
if (!vnc_get_bit(vs->dirty[y + h], last_x)) if (!test_bit(last_x, vs->dirty[y + h])) {
break; 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; return h;
...@@ -905,11 +859,10 @@ static int vnc_update_client(VncState *vs, int has_dirty) ...@@ -905,11 +859,10 @@ static int vnc_update_client(VncState *vs, int has_dirty)
int x; int x;
int last_x = -1; int last_x = -1;
for (x = 0; x < width / 16; x++) { 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) { if (last_x == -1) {
last_x = x; last_x = x;
} }
vnc_clear_bit(vs->dirty[y], x);
} 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);
...@@ -1702,8 +1655,7 @@ static void framebuffer_update_request(VncState *vs, int incremental, ...@@ -1702,8 +1655,7 @@ static void framebuffer_update_request(VncState *vs, int incremental,
if (!incremental) { if (!incremental) {
vs->force_update = 1; vs->force_update = 1;
for (i = 0; i < h; i++) { for (i = 0; i < h; i++) {
vnc_set_bits(vs->dirty[y_position + i], bitmap_set(vs->dirty[y_position + i], x_position / 16, w / 16);
(ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
} }
} }
} }
...@@ -1842,15 +1794,15 @@ static void set_pixel_format(VncState *vs, ...@@ -1842,15 +1794,15 @@ static void set_pixel_format(VncState *vs,
vs->clientds = *(vs->vd->guest.ds); vs->clientds = *(vs->vd->guest.ds);
vs->clientds.pf.rmax = red_max; 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.rshift = red_shift;
vs->clientds.pf.rmask = red_max << red_shift; vs->clientds.pf.rmask = red_max << red_shift;
vs->clientds.pf.gmax = green_max; 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.gshift = green_shift;
vs->clientds.pf.gmask = green_max << green_shift; vs->clientds.pf.gmask = green_max << green_shift;
vs->clientds.pf.bmax = blue_max; 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.bshift = blue_shift;
vs->clientds.pf.bmask = blue_max << blue_shift; vs->clientds.pf.bmask = blue_max << blue_shift;
vs->clientds.pf.bits_per_pixel = bits_per_pixel; 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) ...@@ -2315,7 +2267,7 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
x = x / VNC_STAT_RECT * VNC_STAT_RECT; x = x / VNC_STAT_RECT * VNC_STAT_RECT;
QTAILQ_FOREACH(vs, &vd->clients, next) { QTAILQ_FOREACH(vs, &vd->clients, next) {
int j, i; int j;
/* kernel send buffers are full -> refresh later */ /* kernel send buffers are full -> refresh later */
if (vs->output.offset) { if (vs->output.offset) {
...@@ -2328,9 +2280,7 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y) ...@@ -2328,9 +2280,7 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
vs->lossy_rect[sty][stx] = 0; vs->lossy_rect[sty][stx] = 0;
for (j = 0; j < VNC_STAT_RECT; ++j) { for (j = 0; j < VNC_STAT_RECT; ++j) {
for (i = x / 16; i < VNC_STAT_RECT / 16 + x / 16; ++i) { bitmap_set(vs->dirty[y + j], x / 16, VNC_STAT_RECT / 16);
vnc_set_bit(vs->dirty[y + j], i);
}
} }
has_dirty++; has_dirty++;
} }
...@@ -2433,7 +2383,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd) ...@@ -2433,7 +2383,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
uint8_t *guest_row; uint8_t *guest_row;
uint8_t *server_row; uint8_t *server_row;
int cmp_bytes; int cmp_bytes;
uint32_t width_mask[VNC_DIRTY_WORDS]; unsigned long width_mask[VNC_DIRTY_WORDS];
VncState *vs; VncState *vs;
int has_dirty = 0; int has_dirty = 0;
...@@ -2447,12 +2397,14 @@ static int vnc_refresh_server_surface(VncDisplay *vd) ...@@ -2447,12 +2397,14 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
* Check and copy modified bits from guest to server surface. * Check and copy modified bits from guest to server surface.
* Update server dirty map. * 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); cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
guest_row = vd->guest.ds->data; guest_row = vd->guest.ds->data;
server_row = vd->server->data; server_row = vd->server->data;
for (y = 0; y < vd->guest.ds->height; y++) { 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; int x;
uint8_t *guest_ptr; uint8_t *guest_ptr;
uint8_t *server_ptr; uint8_t *server_ptr;
...@@ -2462,15 +2414,14 @@ static int vnc_refresh_server_surface(VncDisplay *vd) ...@@ -2462,15 +2414,14 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
for (x = 0; x < vd->guest.ds->width; for (x = 0; x < vd->guest.ds->width;
x += 16, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) { 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; continue;
vnc_clear_bit(vd->guest.dirty[y], (x / 16));
if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0) if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0)
continue; continue;
memcpy(server_ptr, guest_ptr, cmp_bytes); memcpy(server_ptr, guest_ptr, cmp_bytes);
vnc_rect_updated(vd, x, y, &tv); vnc_rect_updated(vd, x, y, &tv);
QTAILQ_FOREACH(vs, &vd->clients, next) { QTAILQ_FOREACH(vs, &vd->clients, next) {
vnc_set_bit(vs->dirty[y], (x / 16)); set_bit((x / 16), vs->dirty[y]);
} }
has_dirty++; has_dirty++;
} }
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "console.h" #include "console.h"
#include "monitor.h" #include "monitor.h"
#include "audio/audio.h" #include "audio/audio.h"
#include "bitmap.h"
#include <zlib.h> #include <zlib.h>
#include <stdbool.h> #include <stdbool.h>
...@@ -80,7 +81,7 @@ typedef void VncSendHextileTile(VncState *vs, ...@@ -80,7 +81,7 @@ typedef void VncSendHextileTile(VncState *vs,
#define VNC_MAX_WIDTH 2560 #define VNC_MAX_WIDTH 2560
#define VNC_MAX_HEIGHT 2048 #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_RECT 64
#define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT) #define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
...@@ -113,7 +114,7 @@ typedef struct VncRectStat VncRectStat; ...@@ -113,7 +114,7 @@ typedef struct VncRectStat VncRectStat;
struct VncSurface struct VncSurface
{ {
struct timeval last_freq_check; 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]; VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
DisplaySurface *ds; DisplaySurface *ds;
}; };
...@@ -232,7 +233,7 @@ struct VncState ...@@ -232,7 +233,7 @@ struct VncState
int csock; int csock;
DisplayState *ds; 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 uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
* vnc-jobs-async.c */ * vnc-jobs-async.c */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册