qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 3 of 6] vga shared buffer
Date: Mon, 15 Sep 2008 11:06:49 -0500	[thread overview]
Message-ID: <48CE8819.8070204@codemonkey.ws> (raw)
In-Reply-To: <48CA51E6.1010305@eu.citrix.com>

Stefano Stabellini wrote:
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>   

I need to carve out some time to test this series and think about 
whether it can be done without adding a new DisplayState hook.  I should 
be able to respond or apply within a few days.

I'm concerned about the complexity this adds to back-ends.  It's not 
clear to me whether the performance justifies the added complexity.

Regards,

Anthony Liguori

> ---
>  console.c    |   22 ++++++++++----
>  console.h    |   10 ++++++
>  hw/vga.c     |   88 +++++++++++++++++++++++++++++++++++++++------------------
>  hw/vga_int.h |    2 +
>  4 files changed, 87 insertions(+), 35 deletions(-)
>
> diff --git a/console.c b/console.c
> index 1c94980..f6e6a10 100644
> --- a/console.c
> +++ b/console.c
> @@ -1334,12 +1334,20 @@ CharDriverState *text_console_init(DisplayState *ds, const char *p)
>  
>  void qemu_console_resize(QEMUConsole *console, int width, int height)
>  {
> -    if (console->g_width != width || console->g_height != height
> -        || !console->ds->data) {
> -        console->g_width = width;
> -        console->g_height = height;
> -        if (active_console == console) {
> -            dpy_resize(console->ds, width, height);
> -        }
> +    console->g_width = width;
> +    console->g_height = height;
> +    if (active_console == console) {
> +        dpy_resize(console->ds, width, height);
> +    }
> +}
> +
> +void qemu_console_resize_shared(QEMUConsole *console, int width, int height,
> +                                int depth, int linesize, void *pixels)
> +{
> +    console->g_width = width;
> +    console->g_height = height;
> +    if (active_console == console) {
> +        dpy_resize_shared(console->ds, width, height, depth, linesize, pixels);
>      }
>  }
> +
> diff --git a/console.h b/console.h
> index fcac1eb..a054d97 100644
> --- a/console.h
> +++ b/console.h
> @@ -84,9 +84,12 @@ struct DisplayState {
>      struct QEMUTimer *gui_timer;
>      uint64_t gui_timer_interval;
>      int idle; /* there is nothing to update (window invisible), set by vnc/sdl */
> +    int shared_buf;
>  
>      void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
>      void (*dpy_resize)(struct DisplayState *s, int w, int h);
> +    void (*dpy_resize_shared)(struct DisplayState *s, int w, int h, int depth, int linesize, void *pixels);
> +    void (*dpy_setdata)(DisplayState *s, void *pixels);
>      void (*dpy_refresh)(struct DisplayState *s);
>      void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
>                       int dst_x, int dst_y, int w, int h);
> @@ -108,6 +111,11 @@ static inline void dpy_resize(DisplayState *s, int w, int h)
>      s->dpy_resize(s, w, h);
>  }
>  
> +static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth, int linesize, void *pixels)
> +{
> +    s->dpy_resize_shared(s, w, h, depth, linesize, pixels);
> +}
> +
>  static inline void dpy_cursor(DisplayState *s, int x, int y)
>  {
>      if (s->dpy_text_cursor)
> @@ -140,6 +148,8 @@ CharDriverState *text_console_init(DisplayState *ds, const char *p);
>  void console_select(unsigned int index);
>  void console_color_init(DisplayState *ds);
>  void qemu_console_resize(QEMUConsole *console, int width, int height);
> +void qemu_console_resize_shared(QEMUConsole *console, int width, int height,
> +                                int depth, int linesize, void *pixels);
>  
>  /* sdl.c */
>  void sdl_display_init(DisplayState *ds, int full_screen, int no_frame);
> diff --git a/hw/vga.c b/hw/vga.c
> index eb0bae8..6e40d3d 100644
> --- a/hw/vga.c
> +++ b/hw/vga.c
> @@ -1078,6 +1078,10 @@ static const uint8_t cursor_glyph[32 * 4] = {
>      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
>  };
>  
> +typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
> +
> +static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS];
> +
>  /*
>   * Text mode update
>   * Missing:
> @@ -1099,9 +1103,6 @@ static void vga_draw_text(VGAState *s, int full_update)
>      vga_draw_glyph8_func *vga_draw_glyph8;
>      vga_draw_glyph9_func *vga_draw_glyph9;
>  
> -    full_update |= update_palette16(s);
> -    palette = s->last_palette;
> -
>      /* compute font data address (in plane 2) */
>      v = s->sr[3];
>      offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
> @@ -1135,7 +1136,6 @@ static void vga_draw_text(VGAState *s, int full_update)
>          cw = 9;
>      if (s->sr[1] & 0x08)
>          cw = 16; /* NOTE: no 18 pixel wide */
> -    x_incr = cw * ((s->ds->depth + 7) >> 3);
>      width = (s->cr[0x01] + 1);
>      if (s->cr[0x06] == 100) {
>          /* ugly hack for CGA 160x100x16 - explain me the logic */
> @@ -1152,16 +1152,23 @@ static void vga_draw_text(VGAState *s, int full_update)
>      }
>  
>      if (width != s->last_width || height != s->last_height ||
> -        cw != s->last_cw || cheight != s->last_ch) {
> +        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
>          s->last_scr_width = width * cw;
>          s->last_scr_height = height * cheight;
>          qemu_console_resize(s->console, s->last_scr_width, s->last_scr_height);
> +        s->last_depth = 0;
>          s->last_width = width;
>          s->last_height = height;
>          s->last_ch = cheight;
>          s->last_cw = cw;
>          full_update = 1;
>      }
> +    s->rgb_to_pixel =
> +        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
> +    full_update |= update_palette16(s);
> +    palette = s->last_palette;
> +    x_incr = cw * ((s->ds->depth + 7) >> 3);
> +
>      cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
>      if (cursor_offset != s->cursor_offset ||
>          s->cr[0xa] != s->cursor_start ||
> @@ -1353,8 +1360,6 @@ static vga_draw_line_func *vga_draw_line_table[NB_DEPTHS * VGA_DRAW_LINE_NB] = {
>      vga_draw_line32_16bgr,
>  };
>  
> -typedef unsigned int rgb_to_pixel_dup_func(unsigned int r, unsigned int g, unsigned b);
> -
>  static rgb_to_pixel_dup_func *rgb_to_pixel_dup_table[NB_DEPTHS] = {
>      rgb_to_pixel8_dup,
>      rgb_to_pixel15_dup,
> @@ -1419,6 +1424,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
>  {
>      int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask;
>      int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
> +    int ds_depth, depth, palette_update;
>      int disp_width, multi_scan, multi_run;
>      uint8_t *d;
>      uint32_t v, addr1, addr;
> @@ -1446,8 +1452,39 @@ static void vga_draw_graphic(VGAState *s, int full_update)
>          s->double_scan = double_scan;
>      }
>  
> +    ds_depth = s->ds->depth;
> +    depth = s->get_bpp(s);
> +    if (s->ds->dpy_resize_shared) {
> +        if (s->line_offset != s->last_line_offset || 
> +            disp_width != s->last_width ||
> +            height != s->last_height ||
> +            s->last_depth != depth) {
> +            qemu_console_resize_shared(s->console, disp_width, height,
> +                                       depth, s->line_offset, s->vram_ptr + (s->start_addr * 4));
> +            s->last_scr_width = disp_width;
> +            s->last_scr_height = height;
> +            s->last_width = disp_width;
> +            s->last_height = height;
> +            s->last_line_offset = s->line_offset;
> +            s->last_depth = depth;
> +            full_update = 1;
> +        }
> +    } else if (disp_width != s->last_width ||
> +               height != s->last_height) {
> +        qemu_console_resize(s->console, disp_width, height);
> +        s->last_scr_width = disp_width;
> +        s->last_scr_height = height;
> +        s->last_width = disp_width;
> +        s->last_height = height;
> +        full_update = 1;
> +    }
> +
> +    s->rgb_to_pixel =
> +        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
> +
> +    palette_update = 0;
>      if (shift_control == 0) {
> -        full_update |= update_palette16(s);
> +        palette_update |= update_palette16(s);
>          if (s->sr[0x01] & 8) {
>              v = VGA_DRAW_LINE4D2;
>              disp_width <<= 1;
> @@ -1456,7 +1493,7 @@ static void vga_draw_graphic(VGAState *s, int full_update)
>          }
>          bits = 4;
>      } else if (shift_control == 1) {
> -        full_update |= update_palette16(s);
> +        palette_update |= update_palette16(s);
>          if (s->sr[0x01] & 8) {
>              v = VGA_DRAW_LINE2D2;
>              disp_width <<= 1;
> @@ -1468,12 +1505,12 @@ static void vga_draw_graphic(VGAState *s, int full_update)
>          switch(s->get_bpp(s)) {
>          default:
>          case 0:
> -            full_update |= update_palette256(s);
> +            palette_update |= update_palette256(s);
>              v = VGA_DRAW_LINE8D2;
>              bits = 4;
>              break;
>          case 8:
> -            full_update |= update_palette256(s);
> +            palette_update |= update_palette256(s);
>              v = VGA_DRAW_LINE8;
>              bits = 8;
>              break;
> @@ -1495,18 +1532,12 @@ static void vga_draw_graphic(VGAState *s, int full_update)
>              break;
>          }
>      }
> +    if (s->ds->shared_buf &&
> +        (palette_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
> +        s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
> +    full_update |= palette_update;
>      vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
> -
> -    if (disp_width != s->last_width ||
> -        height != s->last_height) {
> -        qemu_console_resize(s->console, disp_width, height);
> -        s->last_scr_width = disp_width;
> -        s->last_scr_height = height;
> -        s->last_width = disp_width;
> -        s->last_height = height;
> -        full_update = 1;
> -    }
> -    if (s->cursor_invalidate)
> +    if (!s->ds->shared_buf && s->cursor_invalidate)
>          s->cursor_invalidate(s);
>  
>      line_offset = s->line_offset;
> @@ -1552,9 +1583,11 @@ static void vga_draw_graphic(VGAState *s, int full_update)
>                  page_min = page0;
>              if (page1 > page_max)
>                  page_max = page1;
> -            vga_draw_line(s, d, s->vram_ptr + addr, width);
> -            if (s->cursor_draw_line)
> -                s->cursor_draw_line(s, d, y);
> +            if (!s->ds->shared_buf) {
> +                vga_draw_line(s, d, s->vram_ptr + addr, width);
> +                if (s->cursor_draw_line)
> +                    s->cursor_draw_line(s, d, y);
> +            }
>          } else {
>              if (y_start >= 0) {
>                  /* flush to display */
> @@ -1599,6 +1632,8 @@ static void vga_draw_blank(VGAState *s, int full_update)
>          return;
>      if (s->last_scr_width <= 0 || s->last_scr_height <= 0)
>          return;
> +    s->rgb_to_pixel =
> +        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
>      if (s->ds->depth == 8)
>          val = s->rgb_to_pixel(0, 0, 0);
>      else
> @@ -1625,9 +1660,6 @@ static void vga_update_display(void *opaque)
>      if (s->ds->depth == 0) {
>          /* nothing to do */
>      } else {
> -        s->rgb_to_pixel =
> -            rgb_to_pixel_dup_table[get_depth_index(s->ds)];
> -
>          full_update = 0;
>          if (!(s->ar_index & 0x20)) {
>              graphic_mode = GMODE_BLANK;
> diff --git a/hw/vga_int.h b/hw/vga_int.h
> index 343da34..d187f1b 100644
> --- a/hw/vga_int.h
> +++ b/hw/vga_int.h
> @@ -130,9 +130,11 @@
>      uint32_t line_compare;                                              \
>      uint32_t start_addr;                                                \
>      uint32_t plane_updated;                                             \
> +    uint32_t last_line_offset;                                          \
>      uint8_t last_cw, last_ch;                                           \
>      uint32_t last_width, last_height; /* in chars or pixels */          \
>      uint32_t last_scr_width, last_scr_height; /* in pixels */           \
> +    uint32_t last_depth; /* in bits */                                  \
>      uint8_t cursor_start, cursor_end;                                   \
>      uint32_t cursor_offset;                                             \
>      unsigned int (*rgb_to_pixel)(unsigned int r,                        \
>   

  reply	other threads:[~2008-09-15 16:07 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-12 11:26 [Qemu-devel] [PATCH 3 of 6] vga shared buffer Stefano Stabellini
2008-09-15 16:06 ` Anthony Liguori [this message]
2008-09-15 16:47   ` Stefano Stabellini
2008-09-24  3:00   ` andrzej zaborowski
2008-09-24  3:25     ` Anthony Liguori
2008-09-24 10:53     ` Stefano Stabellini

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=48CE8819.8070204@codemonkey.ws \
    --to=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).