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
......@@ -638,30 +638,33 @@ 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;
}
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;
for(y = 0; y < s->height; y++) {
c = s->cells + y1 * s->width;
for(x = 0; x < s->width; x++) {
vga_putcharxy(s->ds, x, y, c->ch,
&(c->t_attrib));
c++;
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;
for (y = 0; y < s->height; y++) {
c = s->cells + y1 * s->width;
for (x = 0; x < s->width; x++) {
vga_putcharxy(s->ds, x, y, c->ch,
&(c->t_attrib));
c++;
}
if (++y1 == s->total_height) {
y1 = 0;
}
}
if (++y1 == s->total_height)
y1 = 0;
console_show_cursor(s, 1);
dpy_gfx_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
}
console_show_cursor(s, 1);
dpy_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,10 +1126,10 @@ 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,
s->update_x1 - s->update_x0,
s->update_y1 - 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);
}
return len;
}
......@@ -1234,8 +1237,8 @@ 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],
s->text_x[1] - s->text_x[0], i - 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;
s->text_x[1] = 0;
......@@ -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);
}
}
......
......@@ -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,
int dst_x, int dst_y, int w, int h);
void (*dpy_fill)(struct DisplayState *s, int x, int y,
int w, int h, uint32_t c);
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_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,
int w, int h, uint32_t c)
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;
......
......@@ -921,8 +921,8 @@ 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],
s->mx[1] - s->mx[0], y - 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;
s->mx[1] = 0;
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -196,7 +196,7 @@ static void jazz_led_update_display(void *opaque)
}
s->state = REDRAW_NONE;
dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
dpy_gfx_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
}
static void jazz_led_invalidate_display(void *opaque)
......@@ -218,7 +218,7 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
console_write_ch(chardata++, 0x00200100 | buf[0]);
console_write_ch(chardata++, 0x00200100 | buf[1]);
dpy_update(s->ds, 0, 0, 2, 1);
dpy_text_update(s->ds, 0, 0, 2, 1);
}
static int jazz_led_post_load(void *opaque, int version_id)
......
......@@ -134,7 +134,7 @@ static void vgafb_update_display(void *opaque)
&first, &last);
if (first >= 0) {
dpy_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
dpy_gfx_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
}
s->invalidate = 0;
}
......
......@@ -526,7 +526,7 @@ static void lcd_refresh(void *opaque)
ds_get_bits_per_pixel(s->ds));
}
dpy_update(s->ds, 0, 0, 128*3, 64*3);
dpy_gfx_update(s->ds, 0, 0, 128*3, 64*3);
}
static void lcd_invalidate(void *opaque)
......
......@@ -1376,7 +1376,7 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
size until the guest activates the display. */
ds = get_displaystate();
ds->surface = qemu_resize_displaysurface(ds, 800, 480);
dpy_resize(ds);
dpy_gfx_resize(ds);
}
static struct arm_boot_info n800_binfo = {
......
......@@ -219,7 +219,7 @@ static void omap_update_display(void *opaque)
draw_line, omap_lcd->palette,
&first, &last);
if (first >= 0) {
dpy_update(omap_lcd->state, 0, first, width, last - first + 1);
dpy_gfx_update(omap_lcd->state, 0, first, width, last - first + 1);
}
omap_lcd->invalidate = 0;
}
......
......@@ -273,7 +273,7 @@ static void palmte_init(QEMUMachineInitArgs *args)
will set the size once configured, so this just sets an initial
size until the guest activates the display. */
ds->surface = qemu_resize_displaysurface(ds, 320, 320);
dpy_resize(ds);
dpy_gfx_resize(ds);
}
static QEMUMachine palmte_machine = {
......
......@@ -239,7 +239,7 @@ static void pl110_update_display(void *opaque)
fn, s->palette,
&first, &last);
if (first >= 0) {
dpy_update(s->ds, 0, first, s->cols, last - first + 1);
dpy_gfx_update(s->ds, 0, first, s->cols, last - first + 1);
}
s->invalidate = 0;
}
......
......@@ -871,20 +871,20 @@ static void pxa2xx_update_display(void *opaque)
if (miny >= 0) {
switch (s->orientation) {
case 0:
dpy_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
dpy_gfx_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
break;
case 90:
dpy_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
dpy_gfx_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
break;
case 180:
maxy = s->yres - maxy - 1;
miny = s->yres - miny - 1;
dpy_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
dpy_gfx_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
break;
case 270:
maxy = s->yres - maxy - 1;
miny = s->yres - miny - 1;
dpy_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
dpy_gfx_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
break;
}
}
......
......@@ -123,17 +123,17 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.surface.width,
qxl->guest_primary.surface.height);
}
dpy_resize(vga->ds);
dpy_gfx_resize(vga->ds);
}
for (i = 0; i < qxl->num_dirty_rects; i++) {
if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
break;
}
qxl_blit(qxl, qxl->dirty+i);
dpy_update(vga->ds,
qxl->dirty[i].left, qxl->dirty[i].top,
qxl->dirty[i].right - qxl->dirty[i].left,
qxl->dirty[i].bottom - qxl->dirty[i].top);
dpy_gfx_update(vga->ds,
qxl->dirty[i].left, qxl->dirty[i].top,
qxl->dirty[i].right - qxl->dirty[i].left,
qxl->dirty[i].bottom - qxl->dirty[i].top);
}
qxl->num_dirty_rects = 0;
}
......
......@@ -1864,8 +1864,8 @@ static void display_refresh(struct DisplayState *ds)
}
static DisplayChangeListener display_listener = {
.dpy_update = display_update,
.dpy_resize = display_resize,
.dpy_gfx_update = display_update,
.dpy_gfx_resize = display_resize,
.dpy_refresh = display_refresh,
};
......
......@@ -1351,7 +1351,7 @@ static void sm501_draw_crt(SM501State * s)
} else {
if (y_start >= 0) {
/* flush to display */
dpy_update(s->ds, 0, y_start, width, y - y_start);
dpy_gfx_update(s->ds, 0, y_start, width, y - y_start);
y_start = -1;
}
}
......@@ -1362,7 +1362,7 @@ static void sm501_draw_crt(SM501State * s)
/* complete flush to display */
if (y_start >= 0)
dpy_update(s->ds, 0, y_start, width, y - y_start);
dpy_gfx_update(s->ds, 0, y_start, width, y - y_start);
/* clear dirty flags */
if (page_min != ~0l) {
......
......@@ -252,7 +252,7 @@ static void ssd0303_update_display(void *opaque)
}
}
s->redraw = 0;
dpy_update(s->ds, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
dpy_gfx_update(s->ds, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
}
static void ssd0303_invalidate_display(void * opaque)
......
......@@ -260,7 +260,7 @@ static void ssd0323_update_display(void *opaque)
}
}
s->redraw = 0;
dpy_update(s->ds, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
dpy_gfx_update(s->ds, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
}
static void ssd0323_invalidate_display(void * opaque)
......
......@@ -454,7 +454,7 @@ static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
return;
}
dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
dpy_gfx_update(s->ds, 0, 0, s->scr_width, s->scr_height);
}
static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
......@@ -472,7 +472,7 @@ static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
d += ds_get_linesize(s->ds);
}
dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
dpy_gfx_update(s->ds, 0, 0, s->scr_width, s->scr_height);
}
static void tc6393xb_update_display(void *opaque)
......
......@@ -268,8 +268,8 @@ static void tcx_update_display(void *opaque)
} else {
if (y_start >= 0) {
/* flush to display */
dpy_update(ts->ds, 0, y_start,
ts->width, y - y_start);
dpy_gfx_update(ts->ds, 0, y_start,
ts->width, y - y_start);
y_start = -1;
}
d += dd * 4;
......@@ -278,8 +278,8 @@ static void tcx_update_display(void *opaque)
}
if (y_start >= 0) {
/* flush to display */
dpy_update(ts->ds, 0, y_start,
ts->width, y - y_start);
dpy_gfx_update(ts->ds, 0, y_start,
ts->width, y - y_start);
}
/* reset modified pages */
if (page_max >= page_min) {
......@@ -344,8 +344,8 @@ static void tcx24_update_display(void *opaque)
} else {
if (y_start >= 0) {
/* flush to display */
dpy_update(ts->ds, 0, y_start,
ts->width, y - y_start);
dpy_gfx_update(ts->ds, 0, y_start,
ts->width, y - y_start);
y_start = -1;
}
d += dd * 4;
......@@ -356,8 +356,8 @@ static void tcx24_update_display(void *opaque)
}
if (y_start >= 0) {
/* flush to display */
dpy_update(ts->ds, 0, y_start,
ts->width, y - y_start);
dpy_gfx_update(ts->ds, 0, y_start,
ts->width, y - y_start);
}
/* reset modified pages */
if (page_max >= page_min) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment