Revision bc2429b9

b/ui/vnc.c
41 41
#include "vnc_keysym.h"
42 42
#include "d3des.h"
43 43

  
44
#define count_bits(c, v) { \
45
    for (c = 0; v; v >>= 1) \
46
    { \
47
        c += v & 1; \
48
    } \
49
}
50

  
51 44
static VncDisplay *vnc_display; /* needed for info vnc */
52 45
static DisplayChangeListener *dcl;
53 46

  
......
378 371
static void vnc_refresh(void *opaque);
379 372
static int vnc_refresh_server_surface(VncDisplay *vd);
380 373

  
381
static inline void vnc_set_bit(uint32_t *d, int k)
382
{
383
    d[k >> 5] |= 1 << (k & 0x1f);
384
}
385

  
386
static inline void vnc_clear_bit(uint32_t *d, int k)
387
{
388
    d[k >> 5] &= ~(1 << (k & 0x1f));
389
}
390

  
391
static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
392
{
393
    int j;
394

  
395
    j = 0;
396
    while (n >= 32) {
397
        d[j++] = -1;
398
        n -= 32;
399
    }
400
    if (n > 0)
401
        d[j++] = (1 << n) - 1;
402
    while (j < nb_words)
403
        d[j++] = 0;
404
}
405

  
406
static inline int vnc_get_bit(const uint32_t *d, int k)
407
{
408
    return (d[k >> 5] >> (k & 0x1f)) & 1;
409
}
410

  
411
static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
412
                               int nb_words)
413
{
414
    int i;
415
    for(i = 0; i < nb_words; i++) {
416
        if ((d1[i] & d2[i]) != 0)
417
            return 1;
418
    }
419
    return 0;
420
}
421

  
422 374
static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
423 375
{
424 376
    int i;
......
441 393

  
442 394
    for (; y < h; y++)
443 395
        for (i = 0; i < w; i += 16)
444
            vnc_set_bit(s->dirty[y], (x + i) / 16);
396
            set_bit((x + i) / 16, s->dirty[y]);
445 397
}
446 398

  
447 399
void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
......
780 732
            memmove(dst_row, src_row, cmp_bytes);
781 733
            QTAILQ_FOREACH(vs, &vd->clients, next) {
782 734
                if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
783
                    vnc_set_bit(vs->dirty[y], ((x + dst_x) / 16));
735
                    set_bit(((x + dst_x) / 16), vs->dirty[y]);
784 736
                }
785 737
            }
786 738
        }
......
850 802

  
851 803
    for (h = 1; h < (vd->server->height - y); h++) {
852 804
        int tmp_x;
853
        if (!vnc_get_bit(vs->dirty[y + h], last_x))
805
        if (!test_bit(last_x, vs->dirty[y + h])) {
854 806
            break;
855
        for (tmp_x = last_x; tmp_x < x; tmp_x++)
856
            vnc_clear_bit(vs->dirty[y + h], tmp_x);
807
        }
808
        for (tmp_x = last_x; tmp_x < x; tmp_x++) {
809
            clear_bit(tmp_x, vs->dirty[y + h]);
810
        }
857 811
    }
858 812

  
859 813
    return h;
......
905 859
            int x;
906 860
            int last_x = -1;
907 861
            for (x = 0; x < width / 16; x++) {
908
                if (vnc_get_bit(vs->dirty[y], x)) {
862
                if (test_and_clear_bit(x, vs->dirty[y])) {
909 863
                    if (last_x == -1) {
910 864
                        last_x = x;
911 865
                    }
912
                    vnc_clear_bit(vs->dirty[y], x);
913 866
                } else {
914 867
                    if (last_x != -1) {
915 868
                        int h = find_and_clear_dirty_height(vs, y, last_x, x);
......
1702 1655
    if (!incremental) {
1703 1656
        vs->force_update = 1;
1704 1657
        for (i = 0; i < h; i++) {
1705
            vnc_set_bits(vs->dirty[y_position + i],
1706
                         (ds_get_width(vs->ds) / 16), VNC_DIRTY_WORDS);
1658
            bitmap_set(vs->dirty[y_position + i], x_position / 16, w / 16);
1707 1659
        }
1708 1660
    }
1709 1661
}
......
1842 1794

  
1843 1795
    vs->clientds = *(vs->vd->guest.ds);
1844 1796
    vs->clientds.pf.rmax = red_max;
1845
    count_bits(vs->clientds.pf.rbits, red_max);
1797
    vs->clientds.pf.rbits = hweight_long(red_max);
1846 1798
    vs->clientds.pf.rshift = red_shift;
1847 1799
    vs->clientds.pf.rmask = red_max << red_shift;
1848 1800
    vs->clientds.pf.gmax = green_max;
1849
    count_bits(vs->clientds.pf.gbits, green_max);
1801
    vs->clientds.pf.gbits = hweight_long(green_max);
1850 1802
    vs->clientds.pf.gshift = green_shift;
1851 1803
    vs->clientds.pf.gmask = green_max << green_shift;
1852 1804
    vs->clientds.pf.bmax = blue_max;
1853
    count_bits(vs->clientds.pf.bbits, blue_max);
1805
    vs->clientds.pf.bbits = hweight_long(blue_max);
1854 1806
    vs->clientds.pf.bshift = blue_shift;
1855 1807
    vs->clientds.pf.bmask = blue_max << blue_shift;
1856 1808
    vs->clientds.pf.bits_per_pixel = bits_per_pixel;
......
2315 2267
    x = x / VNC_STAT_RECT * VNC_STAT_RECT;
2316 2268

  
2317 2269
    QTAILQ_FOREACH(vs, &vd->clients, next) {
2318
        int j, i;
2270
        int j;
2319 2271

  
2320 2272
        /* kernel send buffers are full -> refresh later */
2321 2273
        if (vs->output.offset) {
......
2328 2280

  
2329 2281
        vs->lossy_rect[sty][stx] = 0;
2330 2282
        for (j = 0; j < VNC_STAT_RECT; ++j) {
2331
            for (i = x / 16; i < VNC_STAT_RECT / 16 + x / 16; ++i) {
2332
                vnc_set_bit(vs->dirty[y + j], i);
2333
            }
2283
            bitmap_set(vs->dirty[y + j], x / 16, VNC_STAT_RECT / 16);
2334 2284
        }
2335 2285
        has_dirty++;
2336 2286
    }
......
2433 2383
    uint8_t *guest_row;
2434 2384
    uint8_t *server_row;
2435 2385
    int cmp_bytes;
2436
    uint32_t width_mask[VNC_DIRTY_WORDS];
2386
    unsigned long width_mask[VNC_DIRTY_WORDS];
2437 2387
    VncState *vs;
2438 2388
    int has_dirty = 0;
2439 2389

  
......
2447 2397
     * Check and copy modified bits from guest to server surface.
2448 2398
     * Update server dirty map.
2449 2399
     */
2450
    vnc_set_bits(width_mask, (ds_get_width(vd->ds) / 16), VNC_DIRTY_WORDS);
2400
    bitmap_set(width_mask, 0, (ds_get_width(vd->ds) / 16));
2401
    bitmap_clear(width_mask, (ds_get_width(vd->ds) / 16),
2402
                 VNC_DIRTY_WORDS * BITS_PER_LONG);
2451 2403
    cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
2452 2404
    guest_row  = vd->guest.ds->data;
2453 2405
    server_row = vd->server->data;
2454 2406
    for (y = 0; y < vd->guest.ds->height; y++) {
2455
        if (vnc_and_bits(vd->guest.dirty[y], width_mask, VNC_DIRTY_WORDS)) {
2407
        if (bitmap_intersects(vd->guest.dirty[y], width_mask, VNC_DIRTY_WORDS)) {
2456 2408
            int x;
2457 2409
            uint8_t *guest_ptr;
2458 2410
            uint8_t *server_ptr;
......
2462 2414

  
2463 2415
            for (x = 0; x < vd->guest.ds->width;
2464 2416
                    x += 16, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
2465
                if (!vnc_get_bit(vd->guest.dirty[y], (x / 16)))
2417
                if (!test_and_clear_bit((x / 16), vd->guest.dirty[y]))
2466 2418
                    continue;
2467
                vnc_clear_bit(vd->guest.dirty[y], (x / 16));
2468 2419
                if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0)
2469 2420
                    continue;
2470 2421
                memcpy(server_ptr, guest_ptr, cmp_bytes);
2471 2422
                vnc_rect_updated(vd, x, y, &tv);
2472 2423
                QTAILQ_FOREACH(vs, &vd->clients, next) {
2473
                    vnc_set_bit(vs->dirty[y], (x / 16));
2424
                    set_bit((x / 16), vs->dirty[y]);
2474 2425
                }
2475 2426
                has_dirty++;
2476 2427
            }
b/ui/vnc.h
35 35
#include "console.h"
36 36
#include "monitor.h"
37 37
#include "audio/audio.h"
38
#include "bitmap.h"
38 39
#include <zlib.h>
39 40
#include <stdbool.h>
40 41

  
......
80 81

  
81 82
#define VNC_MAX_WIDTH 2560
82 83
#define VNC_MAX_HEIGHT 2048
83
#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
84
#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * BITS_PER_LONG))
84 85

  
85 86
#define VNC_STAT_RECT  64
86 87
#define VNC_STAT_COLS (VNC_MAX_WIDTH / VNC_STAT_RECT)
......
113 114
struct VncSurface
114 115
{
115 116
    struct timeval last_freq_check;
116
    uint32_t dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
117
    unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
117 118
    VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
118 119
    DisplaySurface *ds;
119 120
};
......
232 233
    int csock;
233 234

  
234 235
    DisplayState *ds;
235
    uint32_t dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
236
    unsigned long dirty[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
236 237
    uint8_t **lossy_rect; /* Not an Array to avoid costly memcpy in
237 238
                           * vnc-jobs-async.c */
238 239

  

Also available in: Unified diff