Commit a93a4a22 authored by Gerd Hoffmann's avatar Gerd Hoffmann
Browse files

console: untangle gfx & txt updates



Stop abusing displaysurface fields for text mode displays.
(bpp = 0, width = cols, height = lines).

Add flags to displaystate indicating whenever text mode display
(curses) or gfx mode displays (sdl, vnc, ...) are present.

Add separate displaychangelistener callbacks for text / gfx mode
resize & updates.

This allows to enable gfx and txt diplays at the same time and also
paves the way for more cleanups in the future.

Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent 76ffb0b4
Loading
Loading
Loading
Loading
+31 −28
Original line number Diff line number Diff line
@@ -638,15 +638,16 @@ static void console_refresh(QemuConsole *s)

    if (s != active_console)
        return;
    if (!ds_get_bits_per_pixel(s->ds)) {

    if (s->ds->have_text) {
        s->text_x[0] = 0;
        s->text_y[0] = 0;
        s->text_x[1] = s->width - 1;
        s->text_y[1] = s->height - 1;
        s->cursor_invalidate = 1;
        return;
    }

    if (s->ds->have_gfx) {
        vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
                      color_table[0][COLOR_BLACK]);
        y1 = s->y_displayed;
@@ -657,11 +658,13 @@ static void console_refresh(QemuConsole *s)
                              &(c->t_attrib));
                c++;
            }
        if (++y1 == s->total_height)
            if (++y1 == s->total_height) {
                y1 = 0;
            }
        }
        console_show_cursor(s, 1);
    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
        dpy_gfx_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
    }
}

static void console_scroll(int ydelta)
@@ -1094,17 +1097,17 @@ void console_select(unsigned int index)
            qemu_del_timer(active_console->cursor_timer);
        }
        active_console = s;
        if (ds_get_bits_per_pixel(s->ds)) {
        if (ds->have_gfx) {
            ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
        } else {
            s->ds->surface->width = s->width;
            s->ds->surface->height = s->height;
            dpy_gfx_resize(ds);
        }
        if (ds->have_text) {
            dpy_text_resize(ds, s->width, s->height);
        }
        if (s->cursor_timer) {
            qemu_mod_timer(s->cursor_timer,
                   qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
        }
        dpy_resize(s->ds);
        vga_hw_invalidate();
    }
}
@@ -1123,8 +1126,8 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
        console_putchar(s, buf[i]);
    }
    console_show_cursor(s, 1);
    if (ds_get_bits_per_pixel(s->ds) && s->update_x0 < s->update_x1) {
        dpy_update(s->ds, s->update_x0, s->update_y0,
    if (s->ds->have_gfx && s->update_x0 < s->update_x1) {
        dpy_gfx_update(s->ds, s->update_x0, s->update_y0,
                       s->update_x1 - s->update_x0,
                       s->update_y1 - s->update_y0);
    }
@@ -1234,7 +1237,7 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
                                (s->cells[src].t_attrib.fgcol << 12) |
                                (s->cells[src].t_attrib.bgcol << 8) |
                                (s->cells[src].t_attrib.bold << 21));
        dpy_update(s->ds, s->text_x[0], s->text_y[0],
        dpy_text_update(s->ds, s->text_x[0], s->text_y[0],
                        s->text_x[1] - s->text_x[0], i - s->text_y[0]);
        s->text_x[0] = s->width;
        s->text_y[0] = s->height;
@@ -1596,7 +1599,7 @@ void qemu_console_resize(DisplayState *ds, int width, int height)
    s->g_height = height;
    if (is_graphic_console()) {
        ds->surface = qemu_resize_displaysurface(ds, width, height);
        dpy_resize(ds);
        dpy_gfx_resize(ds);
    }
}

@@ -1604,7 +1607,7 @@ void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
                       int dst_x, int dst_y, int w, int h)
{
    if (is_graphic_console()) {
        dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
        dpy_gfx_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
    }
}

+52 −22
Original line number Diff line number Diff line
@@ -154,15 +154,19 @@ struct DisplayChangeListener {
    int idle;
    uint64_t gui_timer_interval;

    void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
    void (*dpy_resize)(struct DisplayState *s);
    void (*dpy_setdata)(struct DisplayState *s);
    void (*dpy_refresh)(struct DisplayState *s);
    void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,

    void (*dpy_gfx_update)(struct DisplayState *s, int x, int y, int w, int h);
    void (*dpy_gfx_resize)(struct DisplayState *s);
    void (*dpy_gfx_setdata)(struct DisplayState *s);
    void (*dpy_gfx_copy)(struct DisplayState *s, int src_x, int src_y,
                         int dst_x, int dst_y, int w, int h);
    void (*dpy_fill)(struct DisplayState *s, int x, int y,
    void (*dpy_gfx_fill)(struct DisplayState *s, int x, int y,
                         int w, int h, uint32_t c);

    void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
    void (*dpy_text_resize)(struct DisplayState *s, int w, int h);
    void (*dpy_text_update)(struct DisplayState *s, int x, int y, int w, int h);

    void (*dpy_mouse_set)(struct DisplayState *s, int x, int y, int on);
    void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
@@ -180,6 +184,8 @@ struct DisplayState {
    struct DisplaySurface *surface;
    void *opaque;
    struct QEMUTimer *gui_timer;
    bool have_gfx;
    bool have_text;

    struct DisplayAllocator* allocator;
    QLIST_HEAD(, DisplayChangeListener) listeners;
@@ -244,28 +250,32 @@ static inline void unregister_displaychangelistener(DisplayState *ds,
    gui_setup_refresh(ds);
}

static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
static inline void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
{
    struct DisplayChangeListener *dcl;
    QLIST_FOREACH(dcl, &s->listeners, next) {
        dcl->dpy_update(s, x, y, w, h);
        if (dcl->dpy_gfx_update) {
            dcl->dpy_gfx_update(s, x, y, w, h);
        }
    }
}

static inline void dpy_resize(DisplayState *s)
static inline void dpy_gfx_resize(DisplayState *s)
{
    struct DisplayChangeListener *dcl;
    QLIST_FOREACH(dcl, &s->listeners, next) {
        dcl->dpy_resize(s);
        if (dcl->dpy_gfx_resize) {
            dcl->dpy_gfx_resize(s);
        }
    }
}

static inline void dpy_setdata(DisplayState *s)
static inline void dpy_gfx_setdata(DisplayState *s)
{
    struct DisplayChangeListener *dcl;
    QLIST_FOREACH(dcl, &s->listeners, next) {
        if (dcl->dpy_setdata) {
            dcl->dpy_setdata(s);
        if (dcl->dpy_gfx_setdata) {
            dcl->dpy_gfx_setdata(s);
        }
    }
}
@@ -280,26 +290,26 @@ static inline void dpy_refresh(DisplayState *s)
    }
}

static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
static inline void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
                             int dst_x, int dst_y, int w, int h)
{
    struct DisplayChangeListener *dcl;
    QLIST_FOREACH(dcl, &s->listeners, next) {
        if (dcl->dpy_copy) {
            dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
        if (dcl->dpy_gfx_copy) {
            dcl->dpy_gfx_copy(s, src_x, src_y, dst_x, dst_y, w, h);
        } else { /* TODO */
            dcl->dpy_update(s, dst_x, dst_y, w, h);
            dcl->dpy_gfx_update(s, dst_x, dst_y, w, h);
        }
    }
}

static inline void dpy_fill(struct DisplayState *s, int x, int y,
static inline void dpy_gfx_fill(struct DisplayState *s, int x, int y,
                                int w, int h, uint32_t c)
{
    struct DisplayChangeListener *dcl;
    QLIST_FOREACH(dcl, &s->listeners, next) {
        if (dcl->dpy_fill) {
            dcl->dpy_fill(s, x, y, w, h, c);
        if (dcl->dpy_gfx_fill) {
            dcl->dpy_gfx_fill(s, x, y, w, h, c);
        }
    }
}
@@ -314,6 +324,26 @@ static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
    }
}

static inline void dpy_text_update(DisplayState *s, int x, int y, int w, int h)
{
    struct DisplayChangeListener *dcl;
    QLIST_FOREACH(dcl, &s->listeners, next) {
        if (dcl->dpy_text_update) {
            dcl->dpy_text_update(s, x, y, w, h);
        }
    }
}

static inline void dpy_text_resize(DisplayState *s, int w, int h)
{
    struct DisplayChangeListener *dcl;
    QLIST_FOREACH(dcl, &s->listeners, next) {
        if (dcl->dpy_text_resize) {
            dcl->dpy_text_resize(s, w, h);
        }
    }
}

static inline void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
{
    struct DisplayChangeListener *dcl;
+2 −2
Original line number Diff line number Diff line
@@ -921,7 +921,7 @@ static void blizzard_update_display(void *opaque)
    for (; y < s->my[1]; y ++, src += bypl, dst += bypl)
        memcpy(dst, src, bwidth);

    dpy_update(s->state, s->mx[0], s->my[0],
    dpy_gfx_update(s->state, s->mx[0], s->my[0],
                   s->mx[1] - s->mx[0], y - s->my[0]);

    s->mx[0] = s->x;
+1 −1
Original line number Diff line number Diff line
@@ -1307,7 +1307,7 @@ static void exynos4210_fimd_update(void *opaque)
            fimd_copy_line_toqemu(global_width, s->ifb + global_width * line *
                    RGBA_SIZE, d + global_width * line * bpp);
        }
        dpy_update(s->console, 0, 0, global_width, global_height);
        dpy_gfx_update(s->console, 0, 0, global_width, global_height);
    }
    s->invalidate = false;
    s->vidintcon[1] |= FIMD_VIDINT_INTFRMPEND;
+4 −3
Original line number Diff line number Diff line
@@ -197,7 +197,8 @@ static void g364fb_draw_graphic8(G364State *s)
                reset_dirty(s, page_min, page_max);
                page_min = (ram_addr_t)-1;
                page_max = 0;
                dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
                dpy_gfx_update(s->ds, xmin, ymin,
                               xmax - xmin + 1, ymax - ymin + 1);
                xmin = s->width;
                xmax = 0;
                ymin = s->height;
@@ -216,7 +217,7 @@ static void g364fb_draw_graphic8(G364State *s)

done:
    if (page_min != (ram_addr_t)-1) {
        dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
        dpy_gfx_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
        reset_dirty(s, page_min, page_max);
    }
}
@@ -238,7 +239,7 @@ static void g364fb_draw_blank(G364State *s)
        d += ds_get_linesize(s->ds);
    }

    dpy_update(s->ds, 0, 0, s->width, s->height);
    dpy_gfx_update(s->ds, 0, 0, s->width, s->height);
    s->blanked = 1;
}

Loading