Commit 90a1e3c0b5811d6b334085d56fba1f5f47eaaea3

Authored by aliguori
1 parent 99b3718e

vnc fixes and improvements (Stefano Stabellini)

this patch fixes a bug and improves the generic pixel conversion
function in vnc.c.
The bug is that when a new vnc client connects we need to reset the flag
has_WMVi but currently we don't.
The generic pixel conversion function is vnc_convert_pixel and currently
is not very efficient since uses the division and multiplication
operators.
To make it more efficient I changed to use bit shift operators instead.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6441 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 34 additions and 6 deletions
console.c
... ... @@ -1470,6 +1470,9 @@ PixelFormat qemu_different_endianness_pixelformat(int bpp)
1470 1470 pf.rshift = 0;
1471 1471 pf.gshift = 8;
1472 1472 pf.bshift = 16;
  1473 + pf.rbits = 8;
  1474 + pf.gbits = 8;
  1475 + pf.bbits = 8;
1473 1476 break;
1474 1477 case 32:
1475 1478 pf.rmask = 0x0000FF00;
... ... @@ -1484,6 +1487,10 @@ PixelFormat qemu_different_endianness_pixelformat(int bpp)
1484 1487 pf.rshift = 8;
1485 1488 pf.gshift = 16;
1486 1489 pf.bshift = 24;
  1490 + pf.rbits = 8;
  1491 + pf.gbits = 8;
  1492 + pf.bbits = 8;
  1493 + pf.abits = 8;
1487 1494 break;
1488 1495 default:
1489 1496 break;
... ... @@ -1512,6 +1519,9 @@ PixelFormat qemu_default_pixelformat(int bpp)
1512 1519 pf.rshift = 11;
1513 1520 pf.gshift = 5;
1514 1521 pf.bshift = 0;
  1522 + pf.rbits = 5;
  1523 + pf.gbits = 6;
  1524 + pf.bbits = 5;
1515 1525 break;
1516 1526 case 24:
1517 1527 pf.rmask = 0x00FF0000;
... ... @@ -1523,6 +1533,9 @@ PixelFormat qemu_default_pixelformat(int bpp)
1523 1533 pf.rshift = 16;
1524 1534 pf.gshift = 8;
1525 1535 pf.bshift = 0;
  1536 + pf.rbits = 8;
  1537 + pf.gbits = 8;
  1538 + pf.bbits = 8;
1526 1539 case 32:
1527 1540 pf.rmask = 0x00FF0000;
1528 1541 pf.gmask = 0x0000FF00;
... ... @@ -1535,6 +1548,10 @@ PixelFormat qemu_default_pixelformat(int bpp)
1535 1548 pf.rshift = 16;
1536 1549 pf.gshift = 8;
1537 1550 pf.bshift = 0;
  1551 + pf.rbits = 8;
  1552 + pf.gbits = 8;
  1553 + pf.bbits = 8;
  1554 + pf.abits = 8;
1538 1555 break;
1539 1556 default:
1540 1557 break;
... ...
console.h
... ... @@ -83,6 +83,7 @@ struct PixelFormat {
83 83 uint32_t rmask, gmask, bmask, amask;
84 84 uint8_t rshift, gshift, bshift, ashift;
85 85 uint8_t rmax, gmax, bmax, amax;
  86 + uint8_t rbits, gbits, bbits, abits;
86 87 };
87 88  
88 89 struct DisplaySurface {
... ...
... ... @@ -56,6 +56,12 @@ static void vnc_debug_gnutls_log(int level, const char* str) {
56 56 #define VNC_DEBUG(fmt, ...) do { } while (0)
57 57 #endif
58 58  
  59 +#define count_bits(c, v) { \
  60 + for (c = 0; v; v >>= 1) \
  61 + { \
  62 + c += v & 1; \
  63 + } \
  64 +}
59 65  
60 66 typedef struct Buffer
61 67 {
... ... @@ -329,12 +335,12 @@ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
329 335 {
330 336 uint8_t r, g, b;
331 337  
332   - r = ((v >> vs->serverds.pf.rshift) & vs->serverds.pf.rmax) * (vs->clientds.pf.rmax + 1) /
333   - (vs->serverds.pf.rmax + 1);
334   - g = ((v >> vs->serverds.pf.gshift) & vs->serverds.pf.gmax) * (vs->clientds.pf.gmax + 1) /
335   - (vs->serverds.pf.gmax + 1);
336   - b = ((v >> vs->serverds.pf.bshift) & vs->serverds.pf.bmax) * (vs->clientds.pf.bmax + 1) /
337   - (vs->serverds.pf.bmax + 1);
  338 + r = ((((v & vs->serverds.pf.rmask) >> vs->serverds.pf.rshift) << vs->clientds.pf.rbits) >>
  339 + vs->serverds.pf.rbits);
  340 + g = ((((v & vs->serverds.pf.gmask) >> vs->serverds.pf.gshift) << vs->clientds.pf.gbits) >>
  341 + vs->serverds.pf.gbits);
  342 + b = ((((v & vs->serverds.pf.bmask) >> vs->serverds.pf.bshift) << vs->clientds.pf.bbits) >>
  343 + vs->serverds.pf.bbits);
338 344 v = (r << vs->clientds.pf.rshift) |
339 345 (g << vs->clientds.pf.gshift) |
340 346 (b << vs->clientds.pf.bshift);
... ... @@ -1272,12 +1278,15 @@ static void set_pixel_format(VncState *vs,
1272 1278  
1273 1279 vs->clientds = vs->serverds;
1274 1280 vs->clientds.pf.rmax = red_max;
  1281 + count_bits(vs->clientds.pf.rbits, red_max);
1275 1282 vs->clientds.pf.rshift = red_shift;
1276 1283 vs->clientds.pf.rmask = red_max << red_shift;
1277 1284 vs->clientds.pf.gmax = green_max;
  1285 + count_bits(vs->clientds.pf.gbits, green_max);
1278 1286 vs->clientds.pf.gshift = green_shift;
1279 1287 vs->clientds.pf.gmask = green_max << green_shift;
1280 1288 vs->clientds.pf.bmax = blue_max;
  1289 + count_bits(vs->clientds.pf.bbits, blue_max);
1281 1290 vs->clientds.pf.bshift = blue_shift;
1282 1291 vs->clientds.pf.bmask = blue_max << blue_shift;
1283 1292 vs->clientds.pf.bits_per_pixel = bits_per_pixel;
... ... @@ -2106,6 +2115,7 @@ static void vnc_connect(VncState *vs)
2106 2115 memset(vs->dirty_row, 0xFF, sizeof(vs->dirty_row));
2107 2116 vs->has_resize = 0;
2108 2117 vs->has_hextile = 0;
  2118 + vs->has_WMVi = 0;
2109 2119 dcl->dpy_copy = NULL;
2110 2120 vnc_update_client(vs);
2111 2121 reset_keys(vs);
... ...