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, \
>
next prev parent 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).