Commit 99589bdcd16f20ac5fc45a518fb4633eb90abbfe

Authored by bellard
1 parent 74a14f22

support for higher resolutions


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1956 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 57 additions and 17 deletions
@@ -50,6 +50,10 @@ typedef void VncSendHextileTile(VncState *vs, @@ -50,6 +50,10 @@ typedef void VncSendHextileTile(VncState *vs,
50 uint32_t *last_fg, 50 uint32_t *last_fg,
51 int *has_bg, int *has_fg); 51 int *has_bg, int *has_fg);
52 52
  53 +#define VNC_MAX_WIDTH 2048
  54 +#define VNC_MAX_HEIGHT 2048
  55 +#define VNC_DIRTY_WORDS (VNC_MAX_WIDTH / (16 * 32))
  56 +
53 struct VncState 57 struct VncState
54 { 58 {
55 QEMUTimer *timer; 59 QEMUTimer *timer;
@@ -59,7 +63,7 @@ struct VncState @@ -59,7 +63,7 @@ struct VncState
59 int need_update; 63 int need_update;
60 int width; 64 int width;
61 int height; 65 int height;
62 - uint64_t dirty_row[768]; 66 + uint32_t dirty_row[VNC_MAX_HEIGHT][VNC_DIRTY_WORDS];
63 char *old_data; 67 char *old_data;
64 int depth; /* internal VNC frame buffer byte per pixel */ 68 int depth; /* internal VNC frame buffer byte per pixel */
65 int has_resize; 69 int has_resize;
@@ -95,6 +99,47 @@ static void vnc_flush(VncState *vs); @@ -95,6 +99,47 @@ static void vnc_flush(VncState *vs);
95 static void vnc_update_client(void *opaque); 99 static void vnc_update_client(void *opaque);
96 static void vnc_client_read(void *opaque); 100 static void vnc_client_read(void *opaque);
97 101
  102 +static inline void vnc_set_bit(uint32_t *d, int k)
  103 +{
  104 + d[k >> 5] |= 1 << (k & 0x1f);
  105 +}
  106 +
  107 +static inline void vnc_clear_bit(uint32_t *d, int k)
  108 +{
  109 + d[k >> 5] &= ~(1 << (k & 0x1f));
  110 +}
  111 +
  112 +static inline void vnc_set_bits(uint32_t *d, int n, int nb_words)
  113 +{
  114 + int j;
  115 +
  116 + j = 0;
  117 + while (n >= 32) {
  118 + d[j++] = -1;
  119 + n -= 32;
  120 + }
  121 + if (n > 0)
  122 + d[j++] = (1 << n) - 1;
  123 + while (j < nb_words)
  124 + d[j++] = 0;
  125 +}
  126 +
  127 +static inline int vnc_get_bit(const uint32_t *d, int k)
  128 +{
  129 + return (d[k >> 5] >> (k & 0x1f)) & 1;
  130 +}
  131 +
  132 +static inline int vnc_and_bits(const uint32_t *d1, const uint32_t *d2,
  133 + int nb_words)
  134 +{
  135 + int i;
  136 + for(i = 0; i < nb_words; i++) {
  137 + if ((d1[i] & d2[i]) != 0)
  138 + return 1;
  139 + }
  140 + return 0;
  141 +}
  142 +
98 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) 143 static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
99 { 144 {
100 VncState *vs = ds->opaque; 145 VncState *vs = ds->opaque;
@@ -104,7 +149,7 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h) @@ -104,7 +149,7 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
104 149
105 for (; y < h; y++) 150 for (; y < h; y++)
106 for (i = 0; i < w; i += 16) 151 for (i = 0; i < w; i += 16)
107 - vs->dirty_row[y] |= (1ULL << ((x + i) / 16)); 152 + vnc_set_bit(vs->dirty_row[y], (x + i) / 16);
108 } 153 }
109 154
110 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, 155 static void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
@@ -316,10 +361,10 @@ static int find_dirty_height(VncState *vs, int y, int last_x, int x) @@ -316,10 +361,10 @@ static int find_dirty_height(VncState *vs, int y, int last_x, int x)
316 361
317 for (h = 1; h < (vs->height - y); h++) { 362 for (h = 1; h < (vs->height - y); h++) {
318 int tmp_x; 363 int tmp_x;
319 - if (!(vs->dirty_row[y + h] & (1ULL << last_x))) 364 + if (!vnc_get_bit(vs->dirty_row[y + h], last_x))
320 break; 365 break;
321 for (tmp_x = last_x; tmp_x < x; tmp_x++) 366 for (tmp_x = last_x; tmp_x < x; tmp_x++)
322 - vs->dirty_row[y + h] &= ~(1ULL << tmp_x); 367 + vnc_clear_bit(vs->dirty_row[y + h], tmp_x);
323 } 368 }
324 369
325 return h; 370 return h;
@@ -333,15 +378,12 @@ static void vnc_update_client(void *opaque) @@ -333,15 +378,12 @@ static void vnc_update_client(void *opaque)
333 int y; 378 int y;
334 char *row; 379 char *row;
335 char *old_row; 380 char *old_row;
336 - uint64_t width_mask; 381 + uint32_t width_mask[VNC_DIRTY_WORDS];
337 int n_rectangles; 382 int n_rectangles;
338 int saved_offset; 383 int saved_offset;
339 int has_dirty = 0; 384 int has_dirty = 0;
340 385
341 - width_mask = (1ULL << (vs->width / 16)) - 1;  
342 -  
343 - if (vs->width == 1024)  
344 - width_mask = ~(0ULL); 386 + vnc_set_bits(width_mask, (vs->width / 16), VNC_DIRTY_WORDS);
345 387
346 /* Walk through the dirty map and eliminate tiles that 388 /* Walk through the dirty map and eliminate tiles that
347 really aren't dirty */ 389 really aren't dirty */
@@ -349,7 +391,7 @@ static void vnc_update_client(void *opaque) @@ -349,7 +391,7 @@ static void vnc_update_client(void *opaque)
349 old_row = vs->old_data; 391 old_row = vs->old_data;
350 392
351 for (y = 0; y < vs->height; y++) { 393 for (y = 0; y < vs->height; y++) {
352 - if (vs->dirty_row[y] & width_mask) { 394 + if (vnc_and_bits(vs->dirty_row[y], width_mask, VNC_DIRTY_WORDS)) {
353 int x; 395 int x;
354 char *ptr, *old_ptr; 396 char *ptr, *old_ptr;
355 397
@@ -358,7 +400,7 @@ static void vnc_update_client(void *opaque) @@ -358,7 +400,7 @@ static void vnc_update_client(void *opaque)
358 400
359 for (x = 0; x < vs->ds->width; x += 16) { 401 for (x = 0; x < vs->ds->width; x += 16) {
360 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) { 402 if (memcmp(old_ptr, ptr, 16 * vs->depth) == 0) {
361 - vs->dirty_row[y] &= ~(1ULL << (x / 16)); 403 + vnc_clear_bit(vs->dirty_row[y], (x / 16));
362 } else { 404 } else {
363 has_dirty = 1; 405 has_dirty = 1;
364 memcpy(old_ptr, ptr, 16 * vs->depth); 406 memcpy(old_ptr, ptr, 16 * vs->depth);
@@ -389,11 +431,11 @@ static void vnc_update_client(void *opaque) @@ -389,11 +431,11 @@ static void vnc_update_client(void *opaque)
389 int x; 431 int x;
390 int last_x = -1; 432 int last_x = -1;
391 for (x = 0; x < vs->width / 16; x++) { 433 for (x = 0; x < vs->width / 16; x++) {
392 - if (vs->dirty_row[y] & (1ULL << x)) { 434 + if (vnc_get_bit(vs->dirty_row[y], x)) {
393 if (last_x == -1) { 435 if (last_x == -1) {
394 last_x = x; 436 last_x = x;
395 } 437 }
396 - vs->dirty_row[y] &= ~(1ULL << x); 438 + vnc_clear_bit(vs->dirty_row[y], x);
397 } else { 439 } else {
398 if (last_x != -1) { 440 if (last_x != -1) {
399 int h = find_dirty_height(vs, y, last_x, x); 441 int h = find_dirty_height(vs, y, last_x, x);
@@ -688,10 +730,8 @@ static void framebuffer_update_request(VncState *vs, int incremental, @@ -688,10 +730,8 @@ static void framebuffer_update_request(VncState *vs, int incremental,
688 char *old_row = vs->old_data + y_position * vs->ds->linesize; 730 char *old_row = vs->old_data + y_position * vs->ds->linesize;
689 731
690 for (i = 0; i < h; i++) { 732 for (i = 0; i < h; i++) {
691 - vs->dirty_row[y_position + i] = (1ULL << (vs->ds->width / 16)) - 1;  
692 - if (vs->ds->width == 1024) {  
693 - vs->dirty_row[y_position + i] = ~(0ULL);  
694 - } 733 + vnc_set_bits(vs->dirty_row[y_position + i],
  734 + (vs->ds->width / 16), VNC_DIRTY_WORDS);
695 memset(old_row, 42, vs->ds->width * vs->depth); 735 memset(old_row, 42, vs->ds->width * vs->depth);
696 old_row += vs->ds->linesize; 736 old_row += vs->ds->linesize;
697 } 737 }