All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
To: Anthony Liguori <anthony@codemonkey.ws>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 1 of 3] [UPDATE] vnc dynamic resolution
Date: Mon, 08 Sep 2008 15:05:02 +0100	[thread overview]
Message-ID: <48C5310E.5090506@eu.citrix.com> (raw)
In-Reply-To: <48C474FC.70608@codemonkey.ws>

Anthony Liguori wrote:

> Stefano Stabellini wrote:
>> -#if 0
>>      case 8:
>> -        r = (rgba >> 16) & 0xff;
>> -        g = (rgba >> 8) & 0xff;
>> -        b = (rgba) & 0xff;
>> -        color = (rgb_to_index[r] * 6 * 6) +
>> -            (rgb_to_index[g] * 6) +
>> -            (rgb_to_index[b]);
>> +        color = ((r >> 5) << 5 | (g >> 5) << 2 | (b >> 6));
>>          break;
>> -#endif
>>   
> 
> This fix seems orthogonal to the rest of the patch.  You're adding
> support for an 8-bit DisplayState depth that's 3-3-2.  It would be good
> to document this somewhere.


You are right: I saw the "#if 0" and I just tried to "fix" it.
Reading the code again I realize that this change doesn't make sense for
at least two different reasons, so I'll just drop it.

 
>>  
>> +static void vnc_colourdepth(DisplayState *ds, int depth);
>>   
> 
> For the purposes of consistency, please stick to American English
> spellings.


OK, no problems, I'll start practicing with this email :)

 
>>  static inline void vnc_set_bit(uint32_t *d, int k)
>>  {
>>      d[k >> 5] |= 1 << (k & 0x1f);
>> @@ -332,54 +334,73 @@ static void vnc_write_pixels_copy(VncState *vs,
>> void *pixels, int size)
>>  /* slowest but generic code. */
>>  static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
>>  {
>> -    unsigned int r, g, b;
>> +    uint8_t r, g, b;
>>  
>> -    r = (v >> vs->red_shift1) & vs->red_max;
>> -    g = (v >> vs->green_shift1) & vs->green_max;
>> -    b = (v >> vs->blue_shift1) & vs->blue_max;
>> -    v = (r << vs->red_shift) |
>> -        (g << vs->green_shift) |
>> -        (b << vs->blue_shift);
>> +    r = ((v >> vs->red_shift1) & vs->red_max1) * (vs->red_max + 1) /
>> +        (vs->red_max1 + 1);
>>   
> 
> I don't understand this change.  The code & red_max but then also rounds
> to red_max + 1.  Is this an attempt to handle color maxes that aren't
> power of 2 - 1?  The spec insists that the max is always in the form n^2
> - 1:
> 
> "Red-max is the maximum red value (= 2n − 1 where n is the number of
> bits used for red)."
> 
> Is this just overzealous checks or was a fix for a broken client?


This code is meant to convert pixels from the vnc server internal pixel
format to the vnc client pixel format.
red_max refers to the vnc client red max, while red_max1 refers to the
vnc server internal red max.
Before we were just handling the case red_max1 = 0xff, this code should
be able to handle other cases as well (necessary for handling the shared
buffer).
Does this answer your question? May be with the assumption that red_max
= 2^n - 1 is still possible to simplify the conversion code...

 
>>      switch(vs->pix_bpp) {
>>      case 1:
>> -        buf[0] = v;
>> +        buf[0] = (r << vs->red_shift) | (g << vs->green_shift) |
>> +                 (b << vs->blue_shift);
>>          break;
>>      case 2:
>> +    {
>> +        uint16_t *p = (uint16_t *) buf;
>> +        *p = (r << vs->red_shift) | (g << vs->green_shift) |
>> +             (b << vs->blue_shift);
>>          if (vs->pix_big_endian) {
>> -            buf[0] = v >> 8;
>> -            buf[1] = v;
>> -        } else {
>> -            buf[1] = v >> 8;
>> -            buf[0] = v;
>> +            *p = htons(*p);
>>          }
>>   
> 
> I think this stinks compared to the previous code.  I don't see a
> functional difference between the two.  Can you elaborate on why you
> made this change?


It seems that these last changes can be dropped all together.
The color conversion changes were fixed in multiple steps on
xen-unstable, so now the latter changes seem pointless.
I'll drop them and do all the tests again...

 
>> send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i
>>  {
>>      int i, j;
>>      int has_fg, has_bg;
>> -    uint32_t last_fg32, last_bg32;
>> +    void *last_fg, *last_bg;
>>  
>>      vnc_framebuffer_update(vs, x, y, w, h, 5);
>>  
>> +    last_fg = (void *) malloc(vs->depth);
>> +    last_bg = (void *) malloc(vs->depth);
>>   
> 
> Probably should just have uint8_t last_fg[4], last_bg[4].  That avoids
> error checking on the malloc.


OK.

 
>>      has_fg = has_bg = 0;
>>      for (j = y; j < (y + h); j += 16) {
>>      for (i = x; i < (x + w); i += 16) {
>>              vs->send_hextile_tile(vs, i, j,
>>                                    MIN(16, x + w - i), MIN(16, y + h -
>> j),
>> -                                  &last_bg32, &last_fg32, &has_bg,
>> &has_fg);
>> +                                  last_bg, last_fg, &has_bg, &has_fg);
>>      }
>>      }
>> +    free(last_fg);
>> +    free(last_bg);
>> +
>>  }
>>  
>>  static void send_framebuffer_update(VncState *vs, int x, int y, int
>> w, int h)
>> @@ -1135,17 +1173,6 @@ static void set_encodings(VncState *vs, int32_t
>> *encodings, size_t n_encodings)
>>      check_pointer_type_change(vs, kbd_mouse_is_absolute());
>>  }
>>  
>> -static int compute_nbits(unsigned int val)
>> -{
>> -    int n;
>> -    n = 0;
>> -    while (val != 0) {
>> -        n++;
>> -        val >>= 1;
>> -    }
>> -    return n;
>> -}
>> -
>>  static void set_pixel_format(VncState *vs,
>>                   int bits_per_pixel, int depth,
>>                   int big_endian_flag, int true_color_flag,
>> @@ -1165,6 +1192,7 @@ static void set_pixel_format(VncState *vs,
>>          return;
>>      }
>>      if (bits_per_pixel == 32 &&
>> +        bits_per_pixel == vs->depth * 8 &&
>>          host_big_endian_flag == big_endian_flag &&
>>          red_max == 0xff && green_max == 0xff && blue_max == 0xff &&
>>          red_shift == 16 && green_shift == 8 && blue_shift == 0) {
>> @@ -1173,6 +1201,7 @@ static void set_pixel_format(VncState *vs,
>>          vs->send_hextile_tile = send_hextile_tile_32;
>>      } else
>>      if (bits_per_pixel == 16 &&
>> +        bits_per_pixel == vs->depth * 8 &&         
>> host_big_endian_flag == big_endian_flag &&
>>          red_max == 31 && green_max == 63 && blue_max == 31 &&
>>          red_shift == 11 && green_shift == 5 && blue_shift == 0) {
>> @@ -1181,6 +1210,7 @@ static void set_pixel_format(VncState *vs,
>>          vs->send_hextile_tile = send_hextile_tile_16;
>>      } else
>>      if (bits_per_pixel == 8 &&
>> +        bits_per_pixel == vs->depth * 8 &&
>>          red_max == 7 && green_max == 7 && blue_max == 3 &&
>>          red_shift == 5 && green_shift == 2 && blue_shift == 0) {
>>          vs->depth = 1;
>> @@ -1193,28 +1223,116 @@ static void set_pixel_format(VncState *vs,
>>              bits_per_pixel != 16 &&
>>              bits_per_pixel != 32)
>>              goto fail;
>> -        vs->depth = 4;
>> -        vs->red_shift = red_shift;
>> -        vs->red_max = red_max;
>> -        vs->red_shift1 = 24 - compute_nbits(red_max);
>> -        vs->green_shift = green_shift;
>> -        vs->green_max = green_max;
>> -        vs->green_shift1 = 16 - compute_nbits(green_max);
>> -        vs->blue_shift = blue_shift;
>> -        vs->blue_max = blue_max;
>> -        vs->blue_shift1 = 8 - compute_nbits(blue_max);
>> -        vs->pix_bpp = bits_per_pixel / 8;
>> +        if (vs->depth == 4) {
>> +            vs->send_hextile_tile = send_hextile_tile_generic_32;
>> +        } else if (vs->depth == 2) {
>> +           vs->send_hextile_tile = send_hextile_tile_generic_16;
>> +        } else {
>> +            vs->send_hextile_tile = send_hextile_tile_generic_8;
>> +        }
>> +
>>          vs->pix_big_endian = big_endian_flag;
>>          vs->write_pixels = vnc_write_pixels_generic;
>> -        vs->send_hextile_tile = send_hextile_tile_generic;
>>      }
>>  
>> -    vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height);
>> +    vs->red_shift = red_shift;
>> +    vs->red_max = red_max;
>> +    vs->green_shift = green_shift;
>> +    vs->green_max = green_max;
>> +    vs->blue_shift = blue_shift;
>> +    vs->blue_max = blue_max;
>> +    vs->pix_bpp = bits_per_pixel / 8;
>>   
> 
> I think the previous way was better.  This code seems to be trying to
> deal with red_max that's not in the form of 2^n-1, but it has to be in
> that form according to the spec.
> 

same as before: we are trying to handle a changing vnc server internal
resolution in order to be able to support a shared buffer with the guest.

  reply	other threads:[~2008-09-08 14:03 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-04 14:26 [Qemu-devel] [PATCH 1 of 3] [UPDATE] vnc dynamic resolution Stefano Stabellini
2008-09-08  0:42 ` Anthony Liguori
2008-09-08 14:05   ` Stefano Stabellini [this message]
2008-09-08 14:25     ` Anthony Liguori
2008-09-08 14:32       ` Stefano Stabellini
2008-09-08 14:32         ` Anthony Liguori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48C5310E.5090506@eu.citrix.com \
    --to=stefano.stabellini@eu.citrix.com \
    --cc=anthony@codemonkey.ws \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.