* [Qemu-devel] [PATCH 01/15] pixman: add qemu_pixman_color()
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 21:13 ` Søren Sandmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 02/15] pixman: render vgafont glyphs into pixman images Gerd Hoffmann
` (13 subsequent siblings)
14 siblings, 1 reply; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Helper function to map qemu colors (32bit integer + matching PixelFormat)
into pixman_color_t.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/qemu-pixman.h | 2 ++
ui/qemu-pixman.c | 11 +++++++++++
2 files changed, 13 insertions(+)
diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index b032f52..b0f09b5 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -43,4 +43,6 @@ pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
pixman_image_t *image);
void qemu_pixman_image_unref(pixman_image_t *image);
+pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color);
+
#endif /* QEMU_PIXMAN_H */
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 6dcbe90..be551e0 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -79,3 +79,14 @@ void qemu_pixman_image_unref(pixman_image_t *image)
}
pixman_image_unref(image);
}
+
+pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color)
+{
+ pixman_color_t c;
+
+ c.red = ((color & pf->rmask) >> pf->rshift) << (16 - pf->rbits);
+ c.green = ((color & pf->gmask) >> pf->gshift) << (16 - pf->gbits);
+ c.blue = ((color & pf->bmask) >> pf->bshift) << (16 - pf->bbits);
+ c.alpha = ((color & pf->amask) >> pf->ashift) << (16 - pf->abits);
+ return c;
+}
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 02/15] pixman: render vgafont glyphs into pixman images
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 01/15] pixman: add qemu_pixman_color() Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 03/15] console: use pixman for fill+blit Gerd Hoffmann
` (12 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Add helper functions to create pixman mask images for glyphs
and to render these glyphs into a pixman image.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/qemu-pixman.h | 7 +++++++
ui/qemu-pixman.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index b0f09b5..f012ec5 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -44,5 +44,12 @@ pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
void qemu_pixman_image_unref(pixman_image_t *image);
pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color);
+pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font,
+ unsigned int ch);
+void qemu_pixman_glyph_render(pixman_image_t *glyph,
+ pixman_image_t *surface,
+ pixman_color_t *fgcol,
+ pixman_color_t *bgcol,
+ int x, int y, int cw, int ch);
#endif /* QEMU_PIXMAN_H */
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index be551e0..254bd8c 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -90,3 +90,46 @@ pixman_color_t qemu_pixman_color(PixelFormat *pf, uint32_t color)
c.alpha = ((color & pf->amask) >> pf->ashift) << (16 - pf->abits);
return c;
}
+
+pixman_image_t *qemu_pixman_glyph_from_vgafont(int height, const uint8_t *font,
+ unsigned int ch)
+{
+ pixman_image_t *glyph;
+ uint8_t *data;
+ bool bit;
+ int x, y;
+
+ glyph = pixman_image_create_bits(PIXMAN_a8, 8, height,
+ NULL, 0);
+ data = (uint8_t *)pixman_image_get_data(glyph);
+
+ font += height * ch;
+ for (y = 0; y < height; y++, font++) {
+ for (x = 0; x < 8; x++, data++) {
+ bit = (*font) & (1 << (7-x));
+ *data = bit ? 0xff : 0x00;
+ }
+ }
+ return glyph;
+}
+
+void qemu_pixman_glyph_render(pixman_image_t *glyph,
+ pixman_image_t *surface,
+ pixman_color_t *fgcol,
+ pixman_color_t *bgcol,
+ int x, int y, int cw, int ch)
+{
+ pixman_image_t *ifg = pixman_image_create_solid_fill(fgcol);
+ pixman_image_t *ibg = pixman_image_create_solid_fill(bgcol);
+
+ pixman_image_composite(PIXMAN_OP_SRC, ibg, NULL, surface,
+ 0, 0, 0, 0,
+ cw * x, ch * y,
+ cw, ch);
+ pixman_image_composite(PIXMAN_OP_OVER, ifg, glyph, surface,
+ 0, 0, 0, 0,
+ cw * x, ch * y,
+ cw, ch);
+ pixman_image_unref(ifg);
+ pixman_image_unref(ibg);
+}
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 03/15] console: use pixman for fill+blit
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 01/15] pixman: add qemu_pixman_color() Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 02/15] pixman: render vgafont glyphs into pixman images Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 04/15] console: use pixman for font rendering Gerd Hoffmann
` (11 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Zap homegrown pixel shuffeling code, use pixman calls instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/console.c | 65 +++++++++-------------------------------------------------
1 file changed, 10 insertions(+), 55 deletions(-)
diff --git a/ui/console.c b/ui/console.c
index eb7a2bc..0ec0911 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -213,36 +213,14 @@ static void vga_fill_rect(QemuConsole *con,
uint32_t color)
{
DisplaySurface *surface = qemu_console_surface(con);
- uint8_t *d, *d1;
- int x, y, bpp;
+ pixman_rectangle16_t rect = {
+ .x = posx, .y = posy, .width = width, .height = height
+ };
+ pixman_color_t pcolor;
- bpp = surface_bytes_per_pixel(surface);
- d1 = surface_data(surface) +
- surface_stride(surface) * posy + bpp * posx;
- for (y = 0; y < height; y++) {
- d = d1;
- switch(bpp) {
- case 1:
- for (x = 0; x < width; x++) {
- *((uint8_t *)d) = color;
- d++;
- }
- break;
- case 2:
- for (x = 0; x < width; x++) {
- *((uint16_t *)d) = color;
- d += 2;
- }
- break;
- case 4:
- for (x = 0; x < width; x++) {
- *((uint32_t *)d) = color;
- d += 4;
- }
- break;
- }
- d1 += surface_stride(surface);
- }
+ pcolor = qemu_pixman_color(&surface->pf, color);
+ pixman_image_fill_rectangles(PIXMAN_OP_SRC, surface->image,
+ &pcolor, 1, &rect);
}
/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
@@ -250,33 +228,10 @@ static void vga_bitblt(QemuConsole *con,
int xs, int ys, int xd, int yd, int w, int h)
{
DisplaySurface *surface = qemu_console_surface(con);
- const uint8_t *s;
- uint8_t *d;
- int wb, y, bpp;
- bpp = surface_bytes_per_pixel(surface);
- wb = w * bpp;
- if (yd <= ys) {
- s = surface_data(surface) +
- surface_stride(surface) * ys + bpp * xs;
- d = surface_data(surface) +
- surface_stride(surface) * yd + bpp * xd;
- for (y = 0; y < h; y++) {
- memmove(d, s, wb);
- d += surface_stride(surface);
- s += surface_stride(surface);
- }
- } else {
- s = surface_data(surface) +
- surface_stride(surface) * (ys + h - 1) + bpp * xs;
- d = surface_data(surface) +
- surface_stride(surface) * (yd + h - 1) + bpp * xd;
- for (y = 0; y < h; y++) {
- memmove(d, s, wb);
- d -= surface_stride(surface);
- s -= surface_stride(surface);
- }
- }
+ pixman_image_composite(PIXMAN_OP_SRC,
+ surface->image, NULL, surface->image,
+ xs, ys, 0, 0, xd, yd, w, h);
}
/***********************************************************/
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 04/15] console: use pixman for font rendering
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (2 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 03/15] console: use pixman for fill+blit Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 05/15] console: switch color_table_rgb to pixman_color_t Gerd Hoffmann
` (10 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Zap homegrown font rendering code, use pixman calls instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/console.c | 110 ++++++----------------------------------------------------
1 file changed, 11 insertions(+), 99 deletions(-)
diff --git a/ui/console.c b/ui/console.c
index 0ec0911..4e79268 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -242,45 +242,6 @@ static void vga_bitblt(QemuConsole *con,
#include "vgafont.h"
-#define cbswap_32(__x) \
-((uint32_t)( \
- (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
- (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
- (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
- (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) ))
-
-#ifdef HOST_WORDS_BIGENDIAN
-#define PAT(x) x
-#else
-#define PAT(x) cbswap_32(x)
-#endif
-
-static const uint32_t dmask16[16] = {
- PAT(0x00000000),
- PAT(0x000000ff),
- PAT(0x0000ff00),
- PAT(0x0000ffff),
- PAT(0x00ff0000),
- PAT(0x00ff00ff),
- PAT(0x00ffff00),
- PAT(0x00ffffff),
- PAT(0xff000000),
- PAT(0xff0000ff),
- PAT(0xff00ff00),
- PAT(0xff00ffff),
- PAT(0xffff0000),
- PAT(0xffff00ff),
- PAT(0xffffff00),
- PAT(0xffffffff),
-};
-
-static const uint32_t dmask4[4] = {
- PAT(0x00000000),
- PAT(0x0000ffff),
- PAT(0xffff0000),
- PAT(0xffffffff),
-};
-
#ifndef CONFIG_CURSES
enum color_names {
COLOR_BLACK = 0,
@@ -353,17 +314,11 @@ static void console_print_text_attributes(TextAttributes *t_attrib, char ch)
static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
TextAttributes *t_attrib)
{
+ static pixman_image_t *glyphs[256];
DisplaySurface *surface = qemu_console_surface(s);
- uint8_t *d;
- const uint8_t *font_ptr;
- unsigned int font_data, linesize, xorcol, bpp;
- int i;
unsigned int fgcol, bgcol;
-
-#ifdef DEBUG_CONSOLE
- printf("x: %2i y: %2i", x, y);
- console_print_text_attributes(t_attrib, ch);
-#endif
+ pixman_image_t *ifg, *ibg;
+ pixman_color_t cfg, cbg;
if (t_attrib->invers) {
bgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
@@ -372,59 +327,16 @@ static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
fgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
bgcol = color_table_rgb[t_attrib->bold][t_attrib->bgcol];
}
+ cfg = qemu_pixman_color(&surface->pf, fgcol);
+ cbg = qemu_pixman_color(&surface->pf, bgcol);
+ ifg = pixman_image_create_solid_fill(&cfg);
+ ibg = pixman_image_create_solid_fill(&cbg);
- bpp = surface_bytes_per_pixel(surface);
- d = surface_data(surface) +
- surface_stride(surface) * y * FONT_HEIGHT + bpp * x * FONT_WIDTH;
- linesize = surface_stride(surface);
- font_ptr = vgafont16 + FONT_HEIGHT * ch;
- xorcol = bgcol ^ fgcol;
- switch (surface_bits_per_pixel(surface)) {
- case 8:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- if (t_attrib->uline
- && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
- font_data = 0xFF;
- }
- ((uint32_t *)d)[0] = (dmask16[(font_data >> 4)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask16[(font_data >> 0) & 0xf] & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- case 16:
- case 15:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- if (t_attrib->uline
- && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
- font_data = 0xFF;
- }
- ((uint32_t *)d)[0] = (dmask4[(font_data >> 6)] & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (dmask4[(font_data >> 4) & 3] & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (dmask4[(font_data >> 2) & 3] & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (dmask4[(font_data >> 0) & 3] & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
- case 32:
- for(i = 0; i < FONT_HEIGHT; i++) {
- font_data = *font_ptr++;
- if (t_attrib->uline && ((i == FONT_HEIGHT - 2) || (i == FONT_HEIGHT - 3))) {
- font_data = 0xFF;
- }
- ((uint32_t *)d)[0] = (-((font_data >> 7)) & xorcol) ^ bgcol;
- ((uint32_t *)d)[1] = (-((font_data >> 6) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[2] = (-((font_data >> 5) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[3] = (-((font_data >> 4) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[4] = (-((font_data >> 3) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[5] = (-((font_data >> 2) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[6] = (-((font_data >> 1) & 1) & xorcol) ^ bgcol;
- ((uint32_t *)d)[7] = (-((font_data >> 0) & 1) & xorcol) ^ bgcol;
- d += linesize;
- }
- break;
+ if (!glyphs[ch]) {
+ glyphs[ch] = qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont16, ch);
}
+ qemu_pixman_glyph_render(glyphs[ch], surface->image,
+ &cfg, &cbg, x, y, FONT_WIDTH, FONT_HEIGHT);
}
static void text_console_resize(QemuConsole *s)
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 05/15] console: switch color_table_rgb to pixman_color_t
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (3 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 04/15] console: use pixman for font rendering Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 06/15] console: add trace events Gerd Hoffmann
` (9 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Now that all text console rendering uses pixman we can easily
switch the color tables to use pixman_color_t directly.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/console.c | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/ui/console.c b/ui/console.c
index 4e79268..fbec6cb 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -32,9 +32,6 @@
#define MAX_CONSOLES 12
#define CONSOLE_CURSOR_PERIOD 500
-#define QEMU_RGBA(r, g, b, a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-#define QEMU_RGB(r, g, b) QEMU_RGBA(r, g, b, 0xff)
-
typedef struct TextAttributes {
uint8_t fgcol:4;
uint8_t bgcol:4;
@@ -210,17 +207,15 @@ void vga_hw_text_update(console_ch_t *chardata)
static void vga_fill_rect(QemuConsole *con,
int posx, int posy, int width, int height,
- uint32_t color)
+ pixman_color_t color)
{
DisplaySurface *surface = qemu_console_surface(con);
pixman_rectangle16_t rect = {
.x = posx, .y = posy, .width = width, .height = height
};
- pixman_color_t pcolor;
- pcolor = qemu_pixman_color(&surface->pf, color);
pixman_image_fill_rectangles(PIXMAN_OP_SRC, surface->image,
- &pcolor, 1, &rect);
+ &color, 1, &rect);
}
/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
@@ -255,7 +250,10 @@ enum color_names {
};
#endif
-static const uint32_t color_table_rgb[2][8] = {
+#define QEMU_RGB(r, g, b) \
+ { .red = r << 8, .green = g << 8, .blue = b << 8, .alpha = 0 }
+
+static const pixman_color_t color_table_rgb[2][8] = {
{ /* dark */
QEMU_RGB(0x00, 0x00, 0x00), /* black */
QEMU_RGB(0xaa, 0x00, 0x00), /* red */
@@ -316,9 +314,7 @@ static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
{
static pixman_image_t *glyphs[256];
DisplaySurface *surface = qemu_console_surface(s);
- unsigned int fgcol, bgcol;
- pixman_image_t *ifg, *ibg;
- pixman_color_t cfg, cbg;
+ pixman_color_t fgcol, bgcol;
if (t_attrib->invers) {
bgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
@@ -327,16 +323,12 @@ static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
fgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
bgcol = color_table_rgb[t_attrib->bold][t_attrib->bgcol];
}
- cfg = qemu_pixman_color(&surface->pf, fgcol);
- cbg = qemu_pixman_color(&surface->pf, bgcol);
- ifg = pixman_image_create_solid_fill(&cfg);
- ibg = pixman_image_create_solid_fill(&cbg);
if (!glyphs[ch]) {
glyphs[ch] = qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont16, ch);
}
qemu_pixman_glyph_render(glyphs[ch], surface->image,
- &cfg, &cbg, x, y, FONT_WIDTH, FONT_HEIGHT);
+ &fgcol, &bgcol, x, y, FONT_WIDTH, FONT_HEIGHT);
}
static void text_console_resize(QemuConsole *s)
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 06/15] console: add trace events
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (4 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 05/15] console: switch color_table_rgb to pixman_color_t Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 07/15] console: displaystate init revamp Gerd Hoffmann
` (8 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
trace-events | 3 +++
ui/console.c | 4 ++++
2 files changed, 7 insertions(+)
diff --git a/trace-events b/trace-events
index 406fe5f..c241985 100644
--- a/trace-events
+++ b/trace-events
@@ -958,6 +958,9 @@ dma_bdrv_cb(void *dbs, int ret) "dbs=%p ret=%d"
dma_map_wait(void *dbs) "dbs=%p"
# console.h
+console_gfx_new(void) ""
+console_txt_new(int w, int h) "%dx%d"
+console_select(int nr) "%d"
displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
displaysurface_create_from(void *display_surface, int w, int h, int bpp, int swap) "surface=%p, %dx%d, bpp %d, bswap %d"
displaysurface_free(void *display_surface) "surface=%p"
diff --git a/ui/console.c b/ui/console.c
index fbec6cb..45fa580 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -904,6 +904,8 @@ void console_select(unsigned int index)
if (index >= MAX_CONSOLES)
return;
+
+ trace_console_select(index);
if (active_console) {
surface = qemu_console_surface(active_console);
active_console->g_width = surface_width(surface);
@@ -1367,6 +1369,7 @@ QemuConsole *graphic_console_init(vga_hw_update_ptr update,
DisplayState *ds;
ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
+ trace_console_gfx_new();
s = new_console(ds, GRAPHIC_CONSOLE);
s->hw_update = update;
s->hw_invalidate = invalidate;
@@ -1485,6 +1488,7 @@ static CharDriverState *text_console_init(ChardevVC *vc)
height = vc->rows * FONT_HEIGHT;
}
+ trace_console_txt_new(width, height);
if (width == 0 || height == 0) {
s = new_console(NULL, TEXT_CONSOLE);
} else {
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 07/15] console: displaystate init revamp
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (5 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 06/15] console: add trace events Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 08/15] console: rename vga_hw_*, add QemuConsole param Gerd Hoffmann
` (7 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
We have only one DisplayState, so there is no need for the "next"
linking, rip it. Also consolidate all displaystate initialization
into init_displaystate(). This function is called by vl.c after
creating the devices (and thus all QemuConsoles) and before
initializing DisplayChangeListensers (aka gtk/sdl/vnc/spice ui).
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 5 +---
ui/console.c | 73 +++++++++++++++++++++++---------------------------
vl.c | 6 +----
3 files changed, 36 insertions(+), 48 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index a234c72..3725dae 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -189,12 +189,9 @@ struct DisplayState {
bool have_text;
QLIST_HEAD(, DisplayChangeListener) listeners;
-
- struct DisplayState *next;
};
-void register_displaystate(DisplayState *ds);
-DisplayState *get_displaystate(void);
+DisplayState *init_displaystate(void);
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data,
bool byteswap);
diff --git a/ui/console.c b/ui/console.c
index 45fa580..2c8fd91 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -163,6 +163,8 @@ static QemuConsole *active_console;
static QemuConsole *consoles[MAX_CONSOLES];
static int nb_consoles = 0;
+static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
+
void vga_hw_update(void)
{
if (active_console && active_console->hw_update)
@@ -1323,39 +1325,37 @@ bool dpy_cursor_define_supported(QemuConsole *con)
return false;
}
-static void dumb_display_init(void)
-{
- DisplayState *ds = g_malloc0(sizeof(DisplayState));
- int width = 640;
- int height = 480;
-
- if (is_fixedsize_console()) {
- width = active_console->g_width;
- height = active_console->g_height;
- }
- ds->surface = qemu_create_displaysurface(width, height);
-
- register_displaystate(ds);
-}
-
/***********************************************************/
/* register display */
-void register_displaystate(DisplayState *ds)
+/* console.c internal use only */
+static DisplayState *get_alloc_displaystate(void)
{
- DisplayState **s;
- s = &display_state;
- while (*s != NULL)
- s = &(*s)->next;
- ds->next = NULL;
- *s = ds;
+ if (!display_state) {
+ display_state = g_new0(DisplayState, 1);
+ }
+ return display_state;
}
-DisplayState *get_displaystate(void)
+/*
+ * Called by main(), after creating QemuConsoles
+ * and before initializing ui (sdl/vnc/...).
+ */
+DisplayState *init_displaystate(void)
{
+ int i;
+
if (!display_state) {
- dumb_display_init ();
+ display_state = g_new0(DisplayState, 1);
}
+
+ for (i = 0; i < nb_consoles; i++) {
+ if (consoles[i]->console_type != GRAPHIC_CONSOLE &&
+ consoles[i]->ds == NULL) {
+ text_console_do_init(consoles[i]->chr, display_state);
+ }
+ }
+
return display_state;
}
@@ -1365,10 +1365,12 @@ QemuConsole *graphic_console_init(vga_hw_update_ptr update,
vga_hw_text_update_ptr text_update,
void *opaque)
{
+ int width = 640;
+ int height = 480;
QemuConsole *s;
DisplayState *ds;
- ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
+ ds = get_alloc_displaystate();
trace_console_gfx_new();
s = new_console(ds, GRAPHIC_CONSOLE);
s->hw_update = update;
@@ -1377,9 +1379,9 @@ QemuConsole *graphic_console_init(vga_hw_update_ptr update,
s->hw_text_update = text_update;
s->hw = opaque;
- ds->surface = qemu_create_displaysurface(640, 480);
-
- register_displaystate(ds);
+ if (!ds->surface) {
+ ds->surface = qemu_create_displaysurface(width, height);
+ }
return s;
}
@@ -1505,6 +1507,10 @@ static CharDriverState *text_console_init(ChardevVC *vc)
s->g_height = height;
chr->opaque = s;
chr->chr_set_echo = text_console_set_echo;
+
+ if (display_state) {
+ text_console_do_init(chr, display_state);
+ }
return chr;
}
@@ -1520,17 +1526,6 @@ void register_vc_handler(VcHandler *handler)
vc_handler = handler;
}
-void text_consoles_set_display(DisplayState *ds)
-{
- int i;
-
- for (i = 0; i < nb_consoles; i++) {
- if (consoles[i]->console_type != GRAPHIC_CONSOLE) {
- text_console_do_init(consoles[i]->chr, ds);
- }
- }
-}
-
void qemu_console_resize(QemuConsole *s, int width, int height)
{
s->g_width = width;
diff --git a/vl.c b/vl.c
index ce51e65..c5eb9a7 100644
--- a/vl.c
+++ b/vl.c
@@ -4300,8 +4300,7 @@ int main(int argc, char **argv, char **envp)
net_check_clients();
- /* just use the first displaystate for the moment */
- ds = get_displaystate();
+ ds = init_displaystate();
/* init local displays */
switch (display_type) {
@@ -4357,9 +4356,6 @@ int main(int argc, char **argv, char **envp)
}
#endif
- /* display setup */
- text_consoles_set_display(ds);
-
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
exit(1);
}
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 08/15] console: rename vga_hw_*, add QemuConsole param
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (6 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 07/15] console: displaystate init revamp Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 09/15] console: give each QemuConsole its own DisplaySurface Gerd Hoffmann
` (6 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Add QemuConsole parameter to vga_hw_*, so the interface allows to update
non-active consoles (the actual code can't handle this yet, see next
patch). Passing NULL is allowed and updates the active console, like
the functions do today.
While touching all vga_hw_* calls anyway rename that to the functions to
hardware-neutral graphics_hw_*
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/cirrus_vga.c | 2 +-
hw/qxl.c | 2 +-
hw/vga.c | 2 +-
hw/vga_int.h | 8 ++++----
include/ui/console.h | 22 +++++++++++-----------
ui/console.c | 49 ++++++++++++++++++++++++++++++-------------------
ui/curses.c | 4 ++--
ui/gtk.c | 2 +-
ui/sdl.c | 18 +++++++++---------
ui/spice-display.c | 2 +-
ui/vnc.c | 12 ++++++------
11 files changed, 67 insertions(+), 56 deletions(-)
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 7a4d634..8a0f74f 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -720,7 +720,7 @@ static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
/* we have to flush all pending changes so that the copy
is generated at the appropriate moment in time */
if (notify)
- vga_hw_update();
+ graphic_hw_update(s->vga.con);
(*s->cirrus_rop) (s, s->vga.vram_ptr +
(s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
diff --git a/hw/qxl.c b/hw/qxl.c
index b66b414..1ceee7e 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1074,7 +1074,7 @@ static void qxl_enter_vga_mode(PCIQXLDevice *d)
qemu_spice_create_host_primary(&d->ssd);
d->mode = QXL_MODE_VGA;
vga_dirty_log_start(&d->vga);
- vga_hw_update();
+ graphic_hw_update(d->vga.con);
}
static void qxl_exit_vga_mode(PCIQXLDevice *d)
diff --git a/hw/vga.c b/hw/vga.c
index 59bfb22..533b60e 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2452,6 +2452,6 @@ static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
if (cswitch) {
vga_invalidate_display(s);
}
- vga_hw_update();
+ graphic_hw_update(s->con);
ppm_save(filename, surface, errp);
}
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 260f7d6..1b8f670 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -152,10 +152,10 @@ typedef struct VGACommonState {
uint32_t cursor_offset;
unsigned int (*rgb_to_pixel)(unsigned int r,
unsigned int g, unsigned b);
- vga_hw_update_ptr update;
- vga_hw_invalidate_ptr invalidate;
- vga_hw_screen_dump_ptr screen_dump;
- vga_hw_text_update_ptr text_update;
+ graphic_hw_update_ptr update;
+ graphic_hw_invalidate_ptr invalidate;
+ graphic_hw_screen_dump_ptr screen_dump;
+ graphic_hw_text_update_ptr text_update;
bool full_update_text;
bool full_update_gfx;
/* hardware mouse cursor support */
diff --git a/include/ui/console.h b/include/ui/console.h
index 3725dae..9c585c0 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -278,21 +278,21 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
*dest = ch;
}
-typedef void (*vga_hw_update_ptr)(void *);
-typedef void (*vga_hw_invalidate_ptr)(void *);
-typedef void (*vga_hw_screen_dump_ptr)(void *, const char *, bool cswitch,
+typedef void (*graphic_hw_update_ptr)(void *);
+typedef void (*graphic_hw_invalidate_ptr)(void *);
+typedef void (*graphic_hw_screen_dump_ptr)(void *, const char *, bool cswitch,
Error **errp);
-typedef void (*vga_hw_text_update_ptr)(void *, console_ch_t *);
+typedef void (*graphic_hw_text_update_ptr)(void *, console_ch_t *);
-QemuConsole *graphic_console_init(vga_hw_update_ptr update,
- vga_hw_invalidate_ptr invalidate,
- vga_hw_screen_dump_ptr screen_dump,
- vga_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
+ graphic_hw_invalidate_ptr invalidate,
+ graphic_hw_screen_dump_ptr screen_dump,
+ graphic_hw_text_update_ptr text_update,
void *opaque);
-void vga_hw_update(void);
-void vga_hw_invalidate(void);
-void vga_hw_text_update(console_ch_t *chardata);
+void graphic_hw_update(QemuConsole *con);
+void graphic_hw_invalidate(QemuConsole *con);
+void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata);
int is_graphic_console(void);
int is_fixedsize_console(void);
diff --git a/ui/console.c b/ui/console.c
index 2c8fd91..23eed6f 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -118,10 +118,10 @@ struct QemuConsole {
DisplayState *ds;
/* Graphic console state. */
- vga_hw_update_ptr hw_update;
- vga_hw_invalidate_ptr hw_invalidate;
- vga_hw_screen_dump_ptr hw_screen_dump;
- vga_hw_text_update_ptr hw_text_update;
+ graphic_hw_update_ptr hw_update;
+ graphic_hw_invalidate_ptr hw_invalidate;
+ graphic_hw_screen_dump_ptr hw_screen_dump;
+ graphic_hw_text_update_ptr hw_text_update;
void *hw;
int g_width, g_height;
@@ -165,16 +165,24 @@ static int nb_consoles = 0;
static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
-void vga_hw_update(void)
+void graphic_hw_update(QemuConsole *con)
{
- if (active_console && active_console->hw_update)
- active_console->hw_update(active_console->hw);
+ if (!con) {
+ con = active_console;
+ }
+ if (con && con->hw_update) {
+ con->hw_update(con->hw);
+ }
}
-void vga_hw_invalidate(void)
+void graphic_hw_invalidate(QemuConsole *con)
{
- if (active_console && active_console->hw_invalidate)
- active_console->hw_invalidate(active_console->hw);
+ if (!con) {
+ con = active_console;
+ }
+ if (con && con->hw_invalidate) {
+ con->hw_invalidate(con->hw);
+ }
}
void qmp_screendump(const char *filename, Error **errp)
@@ -201,10 +209,13 @@ void qmp_screendump(const char *filename, Error **errp)
}
}
-void vga_hw_text_update(console_ch_t *chardata)
+void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
{
- if (active_console && active_console->hw_text_update)
- active_console->hw_text_update(active_console->hw, chardata);
+ if (!con) {
+ con = active_console;
+ }
+ if (con && con->hw_text_update)
+ con->hw_text_update(con->hw, chardata);
}
static void vga_fill_rect(QemuConsole *con,
@@ -932,7 +943,7 @@ void console_select(unsigned int index)
qemu_mod_timer(s->cursor_timer,
qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
}
- vga_hw_invalidate();
+ graphic_hw_invalidate(s);
}
}
@@ -1359,10 +1370,10 @@ DisplayState *init_displaystate(void)
return display_state;
}
-QemuConsole *graphic_console_init(vga_hw_update_ptr update,
- vga_hw_invalidate_ptr invalidate,
- vga_hw_screen_dump_ptr screen_dump,
- vga_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
+ graphic_hw_invalidate_ptr invalidate,
+ graphic_hw_screen_dump_ptr screen_dump,
+ graphic_hw_text_update_ptr text_update,
void *opaque)
{
int width = 640;
@@ -1407,7 +1418,7 @@ static void text_console_update_cursor(void *opaque)
QemuConsole *s = opaque;
s->cursor_visible_phase = !s->cursor_visible_phase;
- vga_hw_invalidate();
+ graphic_hw_invalidate(s);
qemu_mod_timer(s->cursor_timer,
qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
}
diff --git a/ui/curses.c b/ui/curses.c
index ff82307..ed9e65c 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -166,11 +166,11 @@ static void curses_refresh(DisplayChangeListener *dcl)
clear();
refresh();
curses_calc_pad();
- vga_hw_invalidate();
+ graphic_hw_invalidate(NULL);
invalidate = 0;
}
- vga_hw_text_update(screen);
+ graphic_hw_text_update(NULL, screen);
nextchr = ERR;
while (1) {
diff --git a/ui/gtk.c b/ui/gtk.c
index 305940d..bccab90 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -300,7 +300,7 @@ static void gd_update(DisplayChangeListener *dcl,
static void gd_refresh(DisplayChangeListener *dcl)
{
- vga_hw_update();
+ graphic_hw_update(NULL);
}
static void gd_switch(DisplayChangeListener *dcl,
diff --git a/ui/sdl.c b/ui/sdl.c
index 8da0534..ede31dc 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -492,8 +492,8 @@ static void toggle_full_screen(void)
sdl_grab_end();
}
}
- vga_hw_invalidate();
- vga_hw_update();
+ graphic_hw_invalidate(NULL);
+ graphic_hw_update(NULL);
}
static void handle_keydown(SDL_Event *ev)
@@ -522,8 +522,8 @@ static void handle_keydown(SDL_Event *ev)
if (scaling_active) {
scaling_active = 0;
sdl_switch(dcl, NULL);
- vga_hw_invalidate();
- vga_hw_update();
+ graphic_hw_invalidate(NULL);
+ graphic_hw_update(NULL);
}
gui_keysym = 1;
break;
@@ -556,8 +556,8 @@ static void handle_keydown(SDL_Event *ev)
surface_width(surface);
sdl_scale(width, height);
- vga_hw_invalidate();
- vga_hw_update();
+ graphic_hw_invalidate(NULL);
+ graphic_hw_update(NULL);
gui_keysym = 1;
}
default:
@@ -770,7 +770,7 @@ static void sdl_refresh(DisplayChangeListener *dcl)
sdl_update_caption();
}
- vga_hw_update();
+ graphic_hw_update(NULL);
SDL_EnableUNICODE(!is_graphic_console());
while (SDL_PollEvent(ev)) {
@@ -802,8 +802,8 @@ static void sdl_refresh(DisplayChangeListener *dcl)
break;
case SDL_VIDEORESIZE:
sdl_scale(ev->resize.w, ev->resize.h);
- vga_hw_invalidate();
- vga_hw_update();
+ graphic_hw_invalidate(NULL);
+ graphic_hw_update(NULL);
break;
default:
break;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index eaab19d..2c01674 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -414,7 +414,7 @@ void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
void qemu_spice_display_refresh(SimpleSpiceDisplay *ssd)
{
dprint(3, "%s:\n", __func__);
- vga_hw_update();
+ graphic_hw_update(ssd->con);
qemu_mutex_lock(&ssd->lock);
if (QTAILQ_EMPTY(&ssd->updates) && ssd->ds) {
diff --git a/ui/vnc.c b/ui/vnc.c
index bbe1e0f..4c32af5 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -1956,8 +1956,8 @@ static void set_pixel_format(VncState *vs,
set_pixel_conversion(vs);
- vga_hw_invalidate();
- vga_hw_update();
+ graphic_hw_invalidate(NULL);
+ graphic_hw_update(NULL);
}
static void pixel_format_message (VncState *vs) {
@@ -2653,7 +2653,7 @@ static void vnc_refresh(void *opaque)
VncState *vs, *vn;
int has_dirty, rects = 0;
- vga_hw_update();
+ graphic_hw_update(NULL);
if (vnc_trylock_display(vd)) {
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
@@ -2692,7 +2692,7 @@ static void vnc_init_timer(VncDisplay *vd)
vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
- vga_hw_update();
+ graphic_hw_update(NULL);
vnc_refresh(vd);
}
}
@@ -2775,7 +2775,7 @@ void vnc_init_state(VncState *vs)
QTAILQ_INSERT_HEAD(&vd->clients, vs, next);
- vga_hw_update();
+ graphic_hw_update(NULL);
vnc_write(vs, "RFB 003.008\n", 12);
vnc_flush(vs);
@@ -2800,7 +2800,7 @@ static void vnc_listen_read(void *opaque, bool websocket)
int csock;
/* Catch-up */
- vga_hw_update();
+ graphic_hw_update(NULL);
#ifdef CONFIG_VNC_WS
if (websocket) {
csock = qemu_accept(vs->lwebsock, (struct sockaddr *)&addr, &addrlen);
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 09/15] console: give each QemuConsole its own DisplaySurface
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (7 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 08/15] console: rename vga_hw_*, add QemuConsole param Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 10/15] console: simplify screendump Gerd Hoffmann
` (5 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Go away from the global DisplaySurface, give one to each QemuConsole
instead. With this patch applied it is possible to call
graphics_hw_* functions with qemu consoles which are not the current
foreground console.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 1 -
ui/console.c | 96 ++++++++++++++++++++++++++++++++++++--------------
2 files changed, 69 insertions(+), 28 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index 9c585c0..0dd66fd 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -183,7 +183,6 @@ struct DisplayChangeListener {
};
struct DisplayState {
- struct DisplaySurface *surface;
struct QEMUTimer *gui_timer;
bool have_gfx;
bool have_text;
diff --git a/ui/console.c b/ui/console.c
index 23eed6f..7687ebc 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -116,6 +116,7 @@ struct QemuConsole {
int index;
console_type_t console_type;
DisplayState *ds;
+ DisplaySurface *surface;
/* Graphic console state. */
graphic_hw_update_ptr hw_update;
@@ -164,6 +165,8 @@ static QemuConsole *consoles[MAX_CONSOLES];
static int nb_consoles = 0;
static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
+static void dpy_gfx_switch_surface(DisplayState *ds,
+ DisplaySurface *surface);
void graphic_hw_update(QemuConsole *con)
{
@@ -933,8 +936,9 @@ void console_select(unsigned int index)
}
active_console = s;
if (ds->have_gfx) {
- surface = qemu_create_displaysurface(s->g_width, s->g_height);
- dpy_gfx_replace_surface(s, surface);
+ dpy_gfx_switch_surface(ds, s->surface);
+ dpy_gfx_update(s, 0, 0, surface_width(s->surface),
+ surface_height(s->surface));
}
if (ds->have_text) {
dpy_text_resize(s, s->width, s->height);
@@ -943,7 +947,6 @@ void console_select(unsigned int index)
qemu_mod_timer(s->cursor_timer,
qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
}
- graphic_hw_invalidate(s);
}
}
@@ -1195,8 +1198,8 @@ void register_displaychangelistener(DisplayState *ds,
dcl->ds = ds;
QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
gui_setup_refresh(ds);
- if (dcl->ops->dpy_gfx_switch) {
- dcl->ops->dpy_gfx_switch(dcl, ds->surface);
+ if (dcl->ops->dpy_gfx_switch && active_console) {
+ dcl->ops->dpy_gfx_switch(dcl, active_console->surface);
}
}
@@ -1212,8 +1215,8 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
{
DisplayState *s = con->ds;
struct DisplayChangeListener *dcl;
- int width = pixman_image_get_width(s->surface->image);
- int height = pixman_image_get_height(s->surface->image);
+ int width = surface_width(con->surface);
+ int height = surface_height(con->surface);
x = MAX(x, 0);
y = MAX(y, 0);
@@ -1222,6 +1225,9 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
w = MIN(w, width - x);
h = MIN(h, height - y);
+ if (con != active_console) {
+ return;
+ }
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_gfx_update) {
dcl->ops->dpy_gfx_update(dcl, x, y, w, h);
@@ -1229,19 +1235,28 @@ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
}
}
-void dpy_gfx_replace_surface(QemuConsole *con,
- DisplaySurface *surface)
+static void dpy_gfx_switch_surface(DisplayState *ds,
+ DisplaySurface *surface)
{
- DisplayState *s = con->ds;
- DisplaySurface *old_surface = s->surface;
struct DisplayChangeListener *dcl;
- s->surface = surface;
- QLIST_FOREACH(dcl, &s->listeners, next) {
+ QLIST_FOREACH(dcl, &ds->listeners, next) {
if (dcl->ops->dpy_gfx_switch) {
dcl->ops->dpy_gfx_switch(dcl, surface);
}
}
+}
+
+void dpy_gfx_replace_surface(QemuConsole *con,
+ DisplaySurface *surface)
+{
+ DisplayState *s = con->ds;
+ DisplaySurface *old_surface = con->surface;
+
+ con->surface = surface;
+ if (con == active_console) {
+ dpy_gfx_switch_surface(s, surface);
+ }
qemu_free_displaysurface(old_surface);
}
@@ -1260,6 +1275,10 @@ void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
{
DisplayState *s = con->ds;
struct DisplayChangeListener *dcl;
+
+ if (con != active_console) {
+ return;
+ }
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_gfx_copy) {
dcl->ops->dpy_gfx_copy(dcl, src_x, src_y, dst_x, dst_y, w, h);
@@ -1273,6 +1292,10 @@ void dpy_text_cursor(QemuConsole *con, int x, int y)
{
DisplayState *s = con->ds;
struct DisplayChangeListener *dcl;
+
+ if (con != active_console) {
+ return;
+ }
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_text_cursor) {
dcl->ops->dpy_text_cursor(dcl, x, y);
@@ -1284,6 +1307,10 @@ void dpy_text_update(QemuConsole *con, int x, int y, int w, int h)
{
DisplayState *s = con->ds;
struct DisplayChangeListener *dcl;
+
+ if (con != active_console) {
+ return;
+ }
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_text_update) {
dcl->ops->dpy_text_update(dcl, x, y, w, h);
@@ -1295,6 +1322,10 @@ void dpy_text_resize(QemuConsole *con, int w, int h)
{
DisplayState *s = con->ds;
struct DisplayChangeListener *dcl;
+
+ if (con != active_console) {
+ return;
+ }
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_text_resize) {
dcl->ops->dpy_text_resize(dcl, w, h);
@@ -1306,6 +1337,10 @@ void dpy_mouse_set(QemuConsole *con, int x, int y, int on)
{
DisplayState *s = con->ds;
struct DisplayChangeListener *dcl;
+
+ if (con != active_console) {
+ return;
+ }
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_mouse_set) {
dcl->ops->dpy_mouse_set(dcl, x, y, on);
@@ -1317,6 +1352,10 @@ void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor)
{
DisplayState *s = con->ds;
struct DisplayChangeListener *dcl;
+
+ if (con != active_console) {
+ return;
+ }
QLIST_FOREACH(dcl, &s->listeners, next) {
if (dcl->ops->dpy_cursor_define) {
dcl->ops->dpy_cursor_define(dcl, cursor);
@@ -1390,9 +1429,7 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
s->hw_text_update = text_update;
s->hw = opaque;
- if (!ds->surface) {
- ds->surface = qemu_create_displaysurface(width, height);
- }
+ s->surface = qemu_create_displaysurface(width, height);
return s;
}
@@ -1442,9 +1479,15 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
s->x = 0;
s->y = 0;
if (s->console_type == TEXT_CONSOLE) {
- s->g_width = surface_width(s->ds->surface);
- s->g_height = surface_height(s->ds->surface);
+ if (active_console && active_console->surface) {
+ s->g_width = surface_width(active_console->surface);
+ s->g_height = surface_height(active_console->surface);
+ } else {
+ s->g_width = 80 * FONT_WIDTH;
+ s->g_height = 24 * FONT_HEIGHT;
+ }
}
+ s->surface = qemu_create_displaysurface(s->g_width, s->g_height);
s->cursor_timer =
qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
@@ -1539,26 +1582,25 @@ void register_vc_handler(VcHandler *handler)
void qemu_console_resize(QemuConsole *s, int width, int height)
{
+ DisplaySurface *surface;
+
+ assert(s->console_type == GRAPHIC_CONSOLE);
s->g_width = width;
s->g_height = height;
- if (is_graphic_console()) {
- DisplaySurface *surface;
- surface = qemu_create_displaysurface(width, height);
- dpy_gfx_replace_surface(s, surface);
- }
+ surface = qemu_create_displaysurface(width, height);
+ dpy_gfx_replace_surface(s, surface);
}
void qemu_console_copy(QemuConsole *con, int src_x, int src_y,
int dst_x, int dst_y, int w, int h)
{
- if (is_graphic_console()) {
- dpy_gfx_copy(con, src_x, src_y, dst_x, dst_y, w, h);
- }
+ assert(con->console_type == GRAPHIC_CONSOLE);
+ dpy_gfx_copy(con, src_x, src_y, dst_x, dst_y, w, h);
}
DisplaySurface *qemu_console_surface(QemuConsole *console)
{
- return console->ds->surface;
+ return console->surface;
}
DisplayState *qemu_console_displaystate(QemuConsole *console)
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 10/15] console: simplify screendump
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (8 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 09/15] console: give each QemuConsole its own DisplaySurface Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 11/15] console: zap g_width + g_height Gerd Hoffmann
` (4 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Anthony Liguori, Guan Xuetao, Igor Mitsyanko,
Evgeny Voevodin, Stefano Stabellini, open list:X86, Gerd Hoffmann,
Maksim Kozlov, Dmitry Solodkiy
Screendumps are alot simpler as we can update non-active
QemuConsoles now. So we only need to update the QemuConsole
we want write out, then dump the DisplaySurface content into
a ppm file. Done.
No console switching needed. No special support code in the
gfx card emulation needed. Zap it all. Also move ppm_save
out of the vga code and next to the qmp_screendump function.
For now screen dumping is limited to console #0 (like it used
to be), even though it is dead simple to extend it to other
consoles. I wanna finish the console cleanup before setting
new qapi interfaces into stone.
---
hw/arm/musicpal.c | 2 +-
hw/blizzard.c | 14 +-----
hw/cirrus_vga.c | 4 +-
hw/exynos4210_fimd.c | 2 +-
hw/g364fb.c | 73 +---------------------------
hw/jazz_led.c | 1 -
hw/milkymist-vgafb.c | 2 +-
hw/omap_lcdc.c | 86 +--------------------------------
hw/pl110.c | 2 +-
hw/pxa2xx_lcd.c | 2 +-
hw/qxl.c | 22 +--------
hw/sm501.c | 2 +-
hw/ssd0303.c | 2 +-
hw/ssd0323.c | 2 +-
hw/tc6393xb.c | 1 -
hw/tcx.c | 129 +-------------------------------------------------
hw/unicore32/puv3.c | 2 +-
hw/vga-isa-mm.c | 2 +-
hw/vga-isa.c | 2 +-
hw/vga-pci.c | 2 +-
hw/vga.c | 66 --------------------------
hw/vga_int.h | 2 -
hw/vmware_vga.c | 26 ----------
hw/xenfb.c | 1 -
include/ui/console.h | 3 --
ui/console.c | 69 +++++++++++++++++++--------
26 files changed, 69 insertions(+), 452 deletions(-)
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index edd5282..4e9a23c 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -612,7 +612,7 @@ static int musicpal_lcd_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->iomem);
s->con = graphic_console_init(lcd_refresh, lcd_invalidate,
- NULL, NULL, s);
+ NULL, s);
qemu_console_resize(s->con, 128*3, 64*3);
qdev_init_gpio_in(&dev->qdev, musicpal_lcd_gpio_brigthness_in, 3);
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 020d3de..891bff8 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -933,18 +933,6 @@ static void blizzard_update_display(void *opaque)
s->my[1] = 0;
}
-static void blizzard_screen_dump(void *opaque, const char *filename,
- bool cswitch, Error **errp)
-{
- BlizzardState *s = (BlizzardState *) opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
-
- blizzard_update_display(opaque);
- if (s && surface_data(surface)) {
- ppm_save(filename, surface, errp);
- }
-}
-
#define DEPTH 8
#include "hw/blizzard_template.h"
#define DEPTH 15
@@ -965,7 +953,7 @@ void *s1d13745_init(qemu_irq gpio_int)
s->con = graphic_console_init(blizzard_update_display,
blizzard_invalidate_display,
- blizzard_screen_dump, NULL, s);
+ NULL, s);
surface = qemu_console_surface(s->con);
switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 8a0f74f..03b3245 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2911,7 +2911,7 @@ static int vga_initfn(ISADevice *dev)
cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
isa_address_space(dev), isa_address_space_io(dev));
s->con = graphic_console_init(s->update, s->invalidate,
- s->screen_dump, s->text_update,
+ s->text_update,
s);
rom_add_vga(VGABIOS_CIRRUS_FILENAME);
/* XXX ISA-LFB support */
@@ -2960,7 +2960,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
cirrus_init_common(s, device_id, 1, pci_address_space(dev),
pci_address_space_io(dev));
s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
- s->vga.screen_dump, s->vga.text_update,
+ s->vga.text_update,
&s->vga);
/* setup PCI */
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index bf316c6..0ae5d26 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1901,7 +1901,7 @@ static int exynos4210_fimd_init(SysBusDevice *dev)
"exynos4210.fimd", FIMD_REGS_SIZE);
sysbus_init_mmio(dev, &s->iomem);
s->console = graphic_console_init(exynos4210_fimd_update,
- exynos4210_fimd_invalidate, NULL, NULL, s);
+ exynos4210_fimd_invalidate, NULL, s);
return 0;
}
diff --git a/hw/g364fb.c b/hw/g364fb.c
index f7014e9..b70fe8a 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -294,77 +294,6 @@ static void g364fb_reset(G364State *s)
g364fb_invalidate_display(s);
}
-static void g364fb_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp)
-{
- G364State *s = opaque;
- int ret, y, x;
- uint8_t index;
- uint8_t *data_buffer;
- FILE *f;
-
- qemu_flush_coalesced_mmio_buffer();
-
- if (s->depth != 8) {
- error_setg(errp, "g364: unknown guest depth %d", s->depth);
- return;
- }
-
- f = fopen(filename, "wb");
- if (!f) {
- error_setg(errp, "failed to open file '%s': %s", filename,
- strerror(errno));
- return;
- }
-
- if (s->ctla & CTLA_FORCE_BLANK) {
- /* blank screen */
- ret = fprintf(f, "P4\n%d %d\n", s->width, s->height);
- if (ret < 0) {
- goto write_err;
- }
- for (y = 0; y < s->height; y++)
- for (x = 0; x < s->width; x++) {
- ret = fputc(0, f);
- if (ret == EOF) {
- goto write_err;
- }
- }
- } else {
- data_buffer = s->vram + s->top_of_screen;
- ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
- if (ret < 0) {
- goto write_err;
- }
- for (y = 0; y < s->height; y++)
- for (x = 0; x < s->width; x++, data_buffer++) {
- index = *data_buffer;
- ret = fputc(s->color_palette[index][0], f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc(s->color_palette[index][1], f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc(s->color_palette[index][2], f);
- if (ret == EOF) {
- goto write_err;
- }
- }
- }
-
-out:
- fclose(f);
- return;
-
-write_err:
- error_setg(errp, "failed to write to file '%s': %s", filename,
- strerror(errno));
- unlink(filename);
- goto out;
-}
-
/* called for accesses to io ports */
static uint64_t g364fb_ctrl_read(void *opaque,
hwaddr addr,
@@ -552,7 +481,7 @@ static void g364fb_init(DeviceState *dev, G364State *s)
s->con = graphic_console_init(g364fb_update_display,
g364fb_invalidate_display,
- g364fb_screen_dump, NULL, s);
+ NULL, s);
memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
memory_region_init_ram_ptr(&s->mem_vram, "vram",
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index 05528c7..c027f76 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -263,7 +263,6 @@ static int jazz_led_init(SysBusDevice *dev)
s->con = graphic_console_init(jazz_led_update_display,
jazz_led_invalidate_display,
- NULL,
jazz_led_text_update, s);
return 0;
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 98762ec..80486e8 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -280,7 +280,7 @@ static int milkymist_vgafb_init(SysBusDevice *dev)
s->con = graphic_console_init(vgafb_update_display,
vgafb_invalidate_display,
- NULL, NULL, s);
+ NULL, s);
return 0;
}
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 4f5b094..1cb49d5 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -227,90 +227,6 @@ static void omap_update_display(void *opaque)
omap_lcd->invalidate = 0;
}
-static void omap_ppm_save(const char *filename, uint8_t *data,
- int w, int h, int linesize, Error **errp)
-{
- FILE *f;
- uint8_t *d, *d1;
- unsigned int v;
- int ret, y, x, bpp;
-
- f = fopen(filename, "wb");
- if (!f) {
- error_setg(errp, "failed to open file '%s': %s", filename,
- strerror(errno));
- return;
- }
- ret = fprintf(f, "P6\n%d %d\n%d\n", w, h, 255);
- if (ret < 0) {
- goto write_err;
- }
- d1 = data;
- bpp = linesize / w;
- for (y = 0; y < h; y ++) {
- d = d1;
- for (x = 0; x < w; x ++) {
- v = *(uint32_t *) d;
- switch (bpp) {
- case 2:
- ret = fputc((v >> 8) & 0xf8, f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc((v >> 3) & 0xfc, f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc((v << 3) & 0xf8, f);
- if (ret == EOF) {
- goto write_err;
- }
- break;
- case 3:
- case 4:
- default:
- ret = fputc((v >> 16) & 0xff, f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc((v >> 8) & 0xff, f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc((v) & 0xff, f);
- if (ret == EOF) {
- goto write_err;
- }
- break;
- }
- d += bpp;
- }
- d1 += linesize;
- }
-out:
- fclose(f);
- return;
-
-write_err:
- error_setg(errp, "failed to write to file '%s': %s", filename,
- strerror(errno));
- unlink(filename);
- goto out;
-}
-
-static void omap_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp)
-{
- struct omap_lcd_panel_s *omap_lcd = opaque;
- DisplaySurface *surface = qemu_console_surface(omap_lcd->con);
-
- omap_update_display(opaque);
- if (omap_lcd && surface_data(surface))
- omap_ppm_save(filename, surface_data(surface),
- omap_lcd->width, omap_lcd->height,
- surface_stride(surface), errp);
-}
-
static void omap_invalidate_display(void *opaque) {
struct omap_lcd_panel_s *omap_lcd = opaque;
omap_lcd->invalidate = 1;
@@ -487,7 +403,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
s->con = graphic_console_init(omap_update_display,
omap_invalidate_display,
- omap_screen_dump, NULL, s);
+ NULL, s);
return s;
}
diff --git a/hw/pl110.c b/hw/pl110.c
index fbef675..6f24957 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -454,7 +454,7 @@ static int pl110_init(SysBusDevice *dev)
qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
s->con = graphic_console_init(pl110_update_display,
pl110_invalidate_display,
- NULL, NULL, s);
+ NULL, s);
return 0;
}
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index f2b0c93..602e3dc 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -1010,7 +1010,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
s->con = graphic_console_init(pxa2xx_update_display,
pxa2xx_invalidate_display,
- NULL, NULL, s);
+ NULL, s);
surface = qemu_console_surface(s->con);
switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 1ceee7e..0f09bae 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1772,26 +1772,6 @@ static void qxl_hw_invalidate(void *opaque)
vga->invalidate(vga);
}
-static void qxl_hw_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp)
-{
- PCIQXLDevice *qxl = opaque;
- VGACommonState *vga = &qxl->vga;
-
- switch (qxl->mode) {
- case QXL_MODE_COMPAT:
- case QXL_MODE_NATIVE:
- qxl_render_update(qxl);
- ppm_save(filename, qxl->ssd.ds, errp);
- break;
- case QXL_MODE_VGA:
- vga->screen_dump(vga, filename, cswitch, errp);
- break;
- default:
- break;
- }
-}
-
static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
{
PCIQXLDevice *qxl = opaque;
@@ -2075,7 +2055,7 @@ static int qxl_init_primary(PCIDevice *dev)
portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
vga->con = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
- qxl_hw_screen_dump, qxl_hw_text_update,
+ qxl_hw_text_update,
qxl);
qxl->ssd.con = vga->con,
qemu_spice_display_init_common(&qxl->ssd);
diff --git a/hw/sm501.c b/hw/sm501.c
index 93a06c9..1f428cd 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1446,5 +1446,5 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
/* create qemu graphic console */
s->con = graphic_console_init(sm501_update_display, NULL,
- NULL, NULL, s);
+ NULL, s);
}
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 68d1f24..02feaff 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -290,7 +290,7 @@ static int ssd0303_init(I2CSlave *i2c)
s->con = graphic_console_init(ssd0303_update_display,
ssd0303_invalidate_display,
- NULL, NULL, s);
+ NULL, s);
qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
return 0;
}
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 5cf2f70..301cb20 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -339,7 +339,7 @@ static int ssd0323_init(SSISlave *dev)
s->row_end = 79;
s->con = graphic_console_init(ssd0323_update_display,
ssd0323_invalidate_display,
- NULL, NULL, s);
+ NULL, s);
qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 79c971b..30b624e 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -585,7 +585,6 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
s->scr_height = 640;
s->con = graphic_console_init(tc6393xb_update_display,
NULL, /* invalidate */
- NULL, /* screen_dump */
NULL, /* text_update */
s);
diff --git a/hw/tcx.c b/hw/tcx.c
index f1edffd..5d12ec4 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -57,11 +57,6 @@ typedef struct TCXState {
uint8_t dac_index, dac_state;
} TCXState;
-static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp);
-static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp);
-
static void tcx_set_dirty(TCXState *s)
{
memory_region_set_dirty(&s->vram_mem, 0, MAXX * MAXY);
@@ -570,7 +565,7 @@ static int tcx_init1(SysBusDevice *dev)
s->con = graphic_console_init(tcx24_update_display,
tcx24_invalidate_display,
- tcx24_screen_dump, NULL, s);
+ NULL, s);
} else {
/* THC 8 bit (dummy) */
memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8",
@@ -579,133 +574,13 @@ static int tcx_init1(SysBusDevice *dev)
s->con = graphic_console_init(tcx_update_display,
tcx_invalidate_display,
- tcx_screen_dump, NULL, s);
+ NULL, s);
}
qemu_console_resize(s->con, s->width, s->height);
return 0;
}
-static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp)
-{
- TCXState *s = opaque;
- FILE *f;
- uint8_t *d, *d1, v;
- int ret, y, x;
-
- f = fopen(filename, "wb");
- if (!f) {
- error_setg(errp, "failed to open file '%s': %s", filename,
- strerror(errno));
- return;
- }
- ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
- if (ret < 0) {
- goto write_err;
- }
- d1 = s->vram;
- for(y = 0; y < s->height; y++) {
- d = d1;
- for(x = 0; x < s->width; x++) {
- v = *d;
- ret = fputc(s->r[v], f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc(s->g[v], f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc(s->b[v], f);
- if (ret == EOF) {
- goto write_err;
- }
- d++;
- }
- d1 += MAXX;
- }
-
-out:
- fclose(f);
- return;
-
-write_err:
- error_setg(errp, "failed to write to file '%s': %s", filename,
- strerror(errno));
- unlink(filename);
- goto out;
-}
-
-static void tcx24_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp)
-{
- TCXState *s = opaque;
- FILE *f;
- uint8_t *d, *d1, v;
- uint32_t *s24, *cptr, dval;
- int ret, y, x;
-
- f = fopen(filename, "wb");
- if (!f) {
- error_setg(errp, "failed to open file '%s': %s", filename,
- strerror(errno));
- return;
- }
- ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);
- if (ret < 0) {
- goto write_err;
- }
- d1 = s->vram;
- s24 = s->vram24;
- cptr = s->cplane;
- for(y = 0; y < s->height; y++) {
- d = d1;
- for(x = 0; x < s->width; x++, d++, s24++) {
- if ((*cptr++ & 0xff000000) == 0x03000000) { // 24-bit direct
- dval = *s24 & 0x00ffffff;
- ret = fputc((dval >> 16) & 0xff, f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc((dval >> 8) & 0xff, f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc(dval & 0xff, f);
- if (ret == EOF) {
- goto write_err;
- }
- } else {
- v = *d;
- ret = fputc(s->r[v], f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc(s->g[v], f);
- if (ret == EOF) {
- goto write_err;
- }
- ret = fputc(s->b[v], f);
- if (ret == EOF) {
- goto write_err;
- }
- }
- }
- d1 += MAXX;
- }
-
-out:
- fclose(f);
- return;
-
-write_err:
- error_setg(errp, "failed to write to file '%s': %s", filename,
- strerror(errno));
- unlink(filename);
- goto out;
-}
-
static Property tcx_properties[] = {
DEFINE_PROP_TADDR("addr", TCXState, addr, -1),
DEFINE_PROP_HEX32("vram_size", TCXState, vram_size, -1),
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 78ab13f..d110363 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -92,7 +92,7 @@ static void puv3_load_kernel(const char *kernel_filename)
}
/* cheat curses that we have a graphic console, only under ocd console */
- graphic_console_init(NULL, NULL, NULL, NULL, NULL);
+ graphic_console_init(NULL, NULL, NULL, NULL);
}
static void puv3_init(QEMUMachineInitArgs *args)
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 02356d4..5fb04fb 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -136,7 +136,7 @@ int isa_vga_mm_init(hwaddr vram_base,
vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
- s->vga.screen_dump, s->vga.text_update,
+ s->vga.text_update,
s);
vga_init_vbe(&s->vga, address_space);
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 9e29321..0a1aded 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -63,7 +63,7 @@ static int vga_initfn(ISADevice *dev)
vga_io_memory, 1);
memory_region_set_coalescing(vga_io_memory);
s->con = graphic_console_init(s->update, s->invalidate,
- s->screen_dump, s->text_update, s);
+ s->text_update, s);
vga_init_vbe(s, isa_address_space(dev));
/* ROM BIOS */
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 05fa9bc..a982f2a 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -151,7 +151,7 @@ static int pci_std_vga_initfn(PCIDevice *dev)
vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
s->con = graphic_console_init(s->update, s->invalidate,
- s->screen_dump, s->text_update, s);
+ s->text_update, s);
/* XXX: VGA_RAM_SIZE must be a power of two */
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
diff --git a/hw/vga.c b/hw/vga.c
index 533b60e..a875faa 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -166,9 +166,6 @@ static uint32_t expand4[256];
static uint16_t expand2[256];
static uint8_t expand4to8[16];
-static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp);
-
static void vga_update_memory_access(VGACommonState *s)
{
MemoryRegion *region, *old_region = s->chain4_alias;
@@ -2298,7 +2295,6 @@ void vga_common_init(VGACommonState *s)
s->get_resolution = vga_get_resolution;
s->update = vga_update_display;
s->invalidate = vga_invalidate_display;
- s->screen_dump = vga_screen_dump;
s->text_update = vga_update_text;
switch (vga_retrace_method) {
case VGA_RETRACE_DUMB:
@@ -2393,65 +2389,3 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
&s->vram_vbe);
s->vbe_mapped = 1;
}
-/********************************************************/
-/* vga screen dump */
-
-void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
-{
- int width = pixman_image_get_width(ds->image);
- int height = pixman_image_get_height(ds->image);
- FILE *f;
- int y;
- int ret;
- pixman_image_t *linebuf;
-
- trace_ppm_save(filename, ds);
- f = fopen(filename, "wb");
- if (!f) {
- error_setg(errp, "failed to open file '%s': %s", filename,
- strerror(errno));
- return;
- }
- ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
- if (ret < 0) {
- linebuf = NULL;
- goto write_err;
- }
- linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
- for (y = 0; y < height; y++) {
- qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
- clearerr(f);
- ret = fwrite(pixman_image_get_data(linebuf), 1,
- pixman_image_get_stride(linebuf), f);
- (void)ret;
- if (ferror(f)) {
- goto write_err;
- }
- }
-
-out:
- qemu_pixman_image_unref(linebuf);
- fclose(f);
- return;
-
-write_err:
- error_setg(errp, "failed to write to file '%s': %s", filename,
- strerror(errno));
- unlink(filename);
- goto out;
-}
-
-/* save the vga display in a PPM image even if no display is
- available */
-static void vga_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp)
-{
- VGACommonState *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->con);
-
- if (cswitch) {
- vga_invalidate_display(s);
- }
- graphic_hw_update(s->con);
- ppm_save(filename, surface, errp);
-}
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 1b8f670..e4bb4a0 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -154,7 +154,6 @@ typedef struct VGACommonState {
unsigned int g, unsigned b);
graphic_hw_update_ptr update;
graphic_hw_invalidate_ptr invalidate;
- graphic_hw_screen_dump_ptr screen_dump;
graphic_hw_text_update_ptr text_update;
bool full_update_text;
bool full_update_gfx;
@@ -198,7 +197,6 @@ void vga_ioport_write(void *opaque, uint32_t addr, uint32_t val);
uint32_t vga_mem_readb(VGACommonState *s, hwaddr addr);
void vga_mem_writeb(VGACommonState *s, hwaddr addr, uint32_t val);
void vga_invalidate_scanlines(VGACommonState *s, int y1, int y2);
-void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp);
int vga_ioport_invalid(VGACommonState *s, uint32_t addr);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 5b9ce8f..4eaa69c 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -1061,31 +1061,6 @@ static void vmsvga_invalidate_display(void *opaque)
s->invalidated = 1;
}
-/* save the vga display in a PPM image even if no display is
- available */
-static void vmsvga_screen_dump(void *opaque, const char *filename, bool cswitch,
- Error **errp)
-{
- struct vmsvga_state_s *s = opaque;
- DisplaySurface *surface = qemu_console_surface(s->vga.con);
-
- if (!s->enable) {
- s->vga.screen_dump(&s->vga, filename, cswitch, errp);
- return;
- }
-
- if (surface_bits_per_pixel(surface) == 32) {
- DisplaySurface *ds = qemu_create_displaysurface_from(
- surface_width(surface),
- surface_height(surface),
- 32,
- surface_stride(surface),
- s->vga.vram_ptr, false);
- ppm_save(filename, ds, errp);
- g_free(ds);
- }
-}
-
static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
{
struct vmsvga_state_s *s = opaque;
@@ -1156,7 +1131,6 @@ static void vmsvga_init(struct vmsvga_state_s *s,
s->vga.con = graphic_console_init(vmsvga_update_display,
vmsvga_invalidate_display,
- vmsvga_screen_dump,
vmsvga_text_update, s);
surface = qemu_console_surface(s->vga.con);
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 7c46a2f..0db2f84 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -1007,7 +1007,6 @@ wait_more:
fb->c.con = graphic_console_init(xenfb_update,
xenfb_invalidate,
NULL,
- NULL,
fb);
fb->have_console = 1;
diff --git a/include/ui/console.h b/include/ui/console.h
index 0dd66fd..d6e3e92 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -279,13 +279,10 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
typedef void (*graphic_hw_update_ptr)(void *);
typedef void (*graphic_hw_invalidate_ptr)(void *);
-typedef void (*graphic_hw_screen_dump_ptr)(void *, const char *, bool cswitch,
- Error **errp);
typedef void (*graphic_hw_text_update_ptr)(void *, console_ch_t *);
QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
graphic_hw_invalidate_ptr invalidate,
- graphic_hw_screen_dump_ptr screen_dump,
graphic_hw_text_update_ptr text_update,
void *opaque);
diff --git a/ui/console.c b/ui/console.c
index 7687ebc..241720b 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -121,7 +121,6 @@ struct QemuConsole {
/* Graphic console state. */
graphic_hw_update_ptr hw_update;
graphic_hw_invalidate_ptr hw_invalidate;
- graphic_hw_screen_dump_ptr hw_screen_dump;
graphic_hw_text_update_ptr hw_text_update;
void *hw;
int g_width, g_height;
@@ -188,28 +187,60 @@ void graphic_hw_invalidate(QemuConsole *con)
}
}
-void qmp_screendump(const char *filename, Error **errp)
+static void ppm_save(const char *filename, struct DisplaySurface *ds,
+ Error **errp)
{
- QemuConsole *previous_active_console;
- bool cswitch;
-
- previous_active_console = active_console;
- cswitch = previous_active_console && previous_active_console->index != 0;
+ int width = pixman_image_get_width(ds->image);
+ int height = pixman_image_get_height(ds->image);
+ FILE *f;
+ int y;
+ int ret;
+ pixman_image_t *linebuf;
- /* There is currently no way of specifying which screen we want to dump,
- so always dump the first one. */
- if (cswitch) {
- console_select(0);
+ trace_ppm_save(filename, ds);
+ f = fopen(filename, "wb");
+ if (!f) {
+ error_setg(errp, "failed to open file '%s': %s", filename,
+ strerror(errno));
+ return;
}
- if (consoles[0] && consoles[0]->hw_screen_dump) {
- consoles[0]->hw_screen_dump(consoles[0]->hw, filename, cswitch, errp);
- } else {
- error_setg(errp, "device doesn't support screendump");
+ ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
+ if (ret < 0) {
+ linebuf = NULL;
+ goto write_err;
+ }
+ linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
+ for (y = 0; y < height; y++) {
+ qemu_pixman_linebuf_fill(linebuf, ds->image, width, 0, y);
+ clearerr(f);
+ ret = fwrite(pixman_image_get_data(linebuf), 1,
+ pixman_image_get_stride(linebuf), f);
+ (void)ret;
+ if (ferror(f)) {
+ goto write_err;
+ }
}
- if (cswitch) {
- console_select(previous_active_console->index);
- }
+out:
+ qemu_pixman_image_unref(linebuf);
+ fclose(f);
+ return;
+
+write_err:
+ error_setg(errp, "failed to write to file '%s': %s", filename,
+ strerror(errno));
+ unlink(filename);
+ goto out;
+}
+
+void qmp_screendump(const char *filename, Error **errp)
+{
+ QemuConsole *con = consoles[0];
+ DisplaySurface *surface;
+
+ graphic_hw_update(con);
+ surface = qemu_console_surface(con);
+ ppm_save(filename, surface, errp);
}
void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
@@ -1411,7 +1442,6 @@ DisplayState *init_displaystate(void)
QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
graphic_hw_invalidate_ptr invalidate,
- graphic_hw_screen_dump_ptr screen_dump,
graphic_hw_text_update_ptr text_update,
void *opaque)
{
@@ -1425,7 +1455,6 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
s = new_console(ds, GRAPHIC_CONSOLE);
s->hw_update = update;
s->hw_invalidate = invalidate;
- s->hw_screen_dump = screen_dump;
s->hw_text_update = text_update;
s->hw = opaque;
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 11/15] console: zap g_width + g_height
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (9 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 10/15] console: simplify screendump Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 12/15] console: move gui_update+gui_setup_refresh from vl.c into console.c Gerd Hoffmann
` (3 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
We have a surface per QemuConsole now, so there is no need to keep
track of the QemuConsole size any more as we can query the surface
size directly at any time.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
ui/console.c | 32 +++++++++-----------------------
1 file changed, 9 insertions(+), 23 deletions(-)
diff --git a/ui/console.c b/ui/console.c
index 241720b..771f155 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -123,7 +123,6 @@ struct QemuConsole {
graphic_hw_invalidate_ptr hw_invalidate;
graphic_hw_text_update_ptr hw_text_update;
void *hw;
- int g_width, g_height;
/* Text console state */
int width;
@@ -384,8 +383,8 @@ static void text_console_resize(QemuConsole *s)
int w1, x, y, last_width;
last_width = s->width;
- s->width = s->g_width / FONT_WIDTH;
- s->height = s->g_height / FONT_HEIGHT;
+ s->width = surface_width(s->surface) / FONT_WIDTH;
+ s->height = surface_height(s->surface) / FONT_HEIGHT;
w1 = last_width;
if (s->width < w1)
@@ -946,18 +945,12 @@ static void console_putchar(QemuConsole *s, int ch)
void console_select(unsigned int index)
{
- DisplaySurface *surface;
QemuConsole *s;
if (index >= MAX_CONSOLES)
return;
trace_console_select(index);
- if (active_console) {
- surface = qemu_console_surface(active_console);
- active_console->g_width = surface_width(surface);
- active_console->g_height = surface_height(surface);
- }
s = consoles[index];
if (s) {
DisplayState *ds = s->ds;
@@ -1084,11 +1077,8 @@ void kbd_put_keysym(int keysym)
static void text_console_invalidate(void *opaque)
{
QemuConsole *s = (QemuConsole *) opaque;
- DisplaySurface *surface = qemu_console_surface(s);
if (s->ds->have_text && s->console_type == TEXT_CONSOLE) {
- s->g_width = surface_width(surface);
- s->g_height = surface_height(surface);
text_console_resize(s);
}
console_refresh(s);
@@ -1492,6 +1482,8 @@ static void text_console_update_cursor(void *opaque)
static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
{
QemuConsole *s;
+ int g_width = 80 * FONT_WIDTH;
+ int g_height = 24 * FONT_HEIGHT;
s = chr->opaque;
@@ -1507,16 +1499,13 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
s->total_height = DEFAULT_BACKSCROLL;
s->x = 0;
s->y = 0;
- if (s->console_type == TEXT_CONSOLE) {
+ if (!s->surface) {
if (active_console && active_console->surface) {
- s->g_width = surface_width(active_console->surface);
- s->g_height = surface_height(active_console->surface);
- } else {
- s->g_width = 80 * FONT_WIDTH;
- s->g_height = 24 * FONT_HEIGHT;
+ g_width = surface_width(active_console->surface);
+ g_height = surface_height(active_console->surface);
}
+ s->surface = qemu_create_displaysurface(g_width, g_height);
}
- s->surface = qemu_create_displaysurface(s->g_width, s->g_height);
s->cursor_timer =
qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
@@ -1578,6 +1567,7 @@ static CharDriverState *text_console_init(ChardevVC *vc)
s = new_console(NULL, TEXT_CONSOLE);
} else {
s = new_console(NULL, TEXT_CONSOLE_FIXED_SIZE);
+ s->surface = qemu_create_displaysurface(width, height);
}
if (!s) {
@@ -1586,8 +1576,6 @@ static CharDriverState *text_console_init(ChardevVC *vc)
}
s->chr = chr;
- s->g_width = width;
- s->g_height = height;
chr->opaque = s;
chr->chr_set_echo = text_console_set_echo;
@@ -1614,8 +1602,6 @@ void qemu_console_resize(QemuConsole *s, int width, int height)
DisplaySurface *surface;
assert(s->console_type == GRAPHIC_CONSOLE);
- s->g_width = width;
- s->g_height = height;
surface = qemu_create_displaysurface(width, height);
dpy_gfx_replace_surface(s, surface);
}
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 12/15] console: move gui_update+gui_setup_refresh from vl.c into console.c
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (10 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 11/15] console: zap g_width + g_height Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 13/15] console: make DisplayState private to console.c Gerd Hoffmann
` (2 subsequent siblings)
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Pure code motion, no functional changes.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 2 --
ui/console.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
vl.c | 49 -------------------------------------------------
3 files changed, 50 insertions(+), 51 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index d6e3e92..d92626b 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -213,8 +213,6 @@ static inline int is_buffer_shared(DisplaySurface *surface)
return !(surface->flags & QEMU_ALLOCATED_FLAG);
}
-void gui_setup_refresh(DisplayState *ds);
-
void register_displaychangelistener(DisplayState *ds,
DisplayChangeListener *dcl);
void unregister_displaychangelistener(DisplayChangeListener *dcl);
diff --git a/ui/console.c b/ui/console.c
index 771f155..8e8f918 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -166,6 +166,56 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
static void dpy_gfx_switch_surface(DisplayState *ds,
DisplaySurface *surface);
+static void gui_update(void *opaque)
+{
+ uint64_t interval = GUI_REFRESH_INTERVAL;
+ DisplayState *ds = opaque;
+ DisplayChangeListener *dcl;
+
+ dpy_refresh(ds);
+
+ QLIST_FOREACH(dcl, &ds->listeners, next) {
+ if (dcl->gui_timer_interval &&
+ dcl->gui_timer_interval < interval) {
+ interval = dcl->gui_timer_interval;
+ }
+ }
+ qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
+}
+
+static void gui_setup_refresh(DisplayState *ds)
+{
+ DisplayChangeListener *dcl;
+ bool need_timer = false;
+ bool have_gfx = false;
+ bool have_text = false;
+
+ QLIST_FOREACH(dcl, &ds->listeners, next) {
+ if (dcl->ops->dpy_refresh != NULL) {
+ need_timer = true;
+ }
+ if (dcl->ops->dpy_gfx_update != NULL) {
+ have_gfx = true;
+ }
+ if (dcl->ops->dpy_text_update != NULL) {
+ have_text = true;
+ }
+ }
+
+ if (need_timer && ds->gui_timer == NULL) {
+ ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
+ qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
+ }
+ if (!need_timer && ds->gui_timer != NULL) {
+ qemu_del_timer(ds->gui_timer);
+ qemu_free_timer(ds->gui_timer);
+ ds->gui_timer = NULL;
+ }
+
+ ds->have_gfx = have_gfx;
+ ds->have_text = have_text;
+}
+
void graphic_hw_update(QemuConsole *con)
{
if (!con) {
diff --git a/vl.c b/vl.c
index c5eb9a7..12ddd83 100644
--- a/vl.c
+++ b/vl.c
@@ -1615,55 +1615,6 @@ MachineInfoList *qmp_query_machines(Error **errp)
/***********************************************************/
/* main execution loop */
-static void gui_update(void *opaque)
-{
- uint64_t interval = GUI_REFRESH_INTERVAL;
- DisplayState *ds = opaque;
- DisplayChangeListener *dcl;
-
- dpy_refresh(ds);
-
- QLIST_FOREACH(dcl, &ds->listeners, next) {
- if (dcl->gui_timer_interval &&
- dcl->gui_timer_interval < interval)
- interval = dcl->gui_timer_interval;
- }
- qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
-}
-
-void gui_setup_refresh(DisplayState *ds)
-{
- DisplayChangeListener *dcl;
- bool need_timer = false;
- bool have_gfx = false;
- bool have_text = false;
-
- QLIST_FOREACH(dcl, &ds->listeners, next) {
- if (dcl->ops->dpy_refresh != NULL) {
- need_timer = true;
- }
- if (dcl->ops->dpy_gfx_update != NULL) {
- have_gfx = true;
- }
- if (dcl->ops->dpy_text_update != NULL) {
- have_text = true;
- }
- }
-
- if (need_timer && ds->gui_timer == NULL) {
- ds->gui_timer = qemu_new_timer_ms(rt_clock, gui_update, ds);
- qemu_mod_timer(ds->gui_timer, qemu_get_clock_ms(rt_clock));
- }
- if (!need_timer && ds->gui_timer != NULL) {
- qemu_del_timer(ds->gui_timer);
- qemu_free_timer(ds->gui_timer);
- ds->gui_timer = NULL;
- }
-
- ds->have_gfx = have_gfx;
- ds->have_text = have_text;
-}
-
struct vm_change_state_entry {
VMChangeStateHandler *cb;
void *opaque;
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 13/15] console: make DisplayState private to console.c
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (11 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 12/15] console: move gui_update+gui_setup_refresh from vl.c into console.c Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 14/15] console: add GraphicHwOps Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 15/15] console: gui timer fixes Gerd Hoffmann
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
With gui_* being moved to console.c nobody outside console.c needs
access to DisplayState fields any more. Make the struct private.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 8 --------
ui/console.c | 8 ++++++++
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index d92626b..50cd7b0 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -182,14 +182,6 @@ struct DisplayChangeListener {
QLIST_ENTRY(DisplayChangeListener) next;
};
-struct DisplayState {
- struct QEMUTimer *gui_timer;
- bool have_gfx;
- bool have_text;
-
- QLIST_HEAD(, DisplayChangeListener) listeners;
-};
-
DisplayState *init_displaystate(void);
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data,
diff --git a/ui/console.c b/ui/console.c
index 8e8f918..c22895f 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -157,6 +157,14 @@ struct QemuConsole {
QEMUTimer *kbd_timer;
};
+struct DisplayState {
+ struct QEMUTimer *gui_timer;
+ bool have_gfx;
+ bool have_text;
+
+ QLIST_HEAD(, DisplayChangeListener) listeners;
+};
+
static DisplayState *display_state;
static QemuConsole *active_console;
static QemuConsole *consoles[MAX_CONSOLES];
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 14/15] console: add GraphicHwOps
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (12 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 13/15] console: make DisplayState private to console.c Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
2013-03-18 12:09 ` [Qemu-devel] [PATCH 15/15] console: gui timer fixes Gerd Hoffmann
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel
Cc: Peter Maydell, Anthony Liguori, Guan Xuetao, Igor Mitsyanko,
Evgeny Voevodin, Stefano Stabellini, open list:X86, Gerd Hoffmann,
Maksim Kozlov, Dmitry Solodkiy
Pass a single GraphicHwOps struct pointer to graphic_console_init,
instead of a bunch of function pointers.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/arm/musicpal.c | 8 ++++++--
hw/blizzard.c | 9 ++++++---
hw/cirrus_vga.c | 8 ++------
hw/exynos4210_fimd.c | 8 ++++++--
hw/g364fb.c | 9 ++++++---
hw/jazz_led.c | 10 +++++++---
hw/milkymist-vgafb.c | 9 ++++++---
hw/omap_lcdc.c | 9 ++++++---
hw/pl110.c | 9 ++++++---
hw/pxa2xx_lcd.c | 9 ++++++---
hw/qxl.c | 16 ++++++++++------
hw/sm501.c | 7 +++++--
hw/ssd0303.c | 9 ++++++---
hw/ssd0323.c | 9 ++++++---
hw/tc6393xb.c | 9 +++++----
hw/tcx.c | 18 ++++++++++++------
hw/unicore32/puv3.c | 4 +++-
hw/vga-isa-mm.c | 4 +---
hw/vga-isa.c | 3 +--
hw/vga-pci.c | 3 +--
hw/vga.c | 10 +++++++---
hw/vga_int.h | 4 +---
hw/vmware_vga.c | 20 ++++++++++++--------
hw/xenfb.c | 10 ++++++----
include/ui/console.h | 12 ++++++------
ui/console.c | 32 +++++++++++++++-----------------
26 files changed, 154 insertions(+), 104 deletions(-)
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index 4e9a23c..7d3e239 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -601,6 +601,11 @@ static const MemoryRegionOps musicpal_lcd_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static const GraphicHwOps musicpal_gfx_ops = {
+ .invalidate = lcd_invalidate,
+ .gfx_update = lcd_refresh,
+};
+
static int musicpal_lcd_init(SysBusDevice *dev)
{
musicpal_lcd_state *s = FROM_SYSBUS(musicpal_lcd_state, dev);
@@ -611,8 +616,7 @@ static int musicpal_lcd_init(SysBusDevice *dev)
"musicpal-lcd", MP_LCD_SIZE);
sysbus_init_mmio(dev, &s->iomem);
- s->con = graphic_console_init(lcd_refresh, lcd_invalidate,
- NULL, s);
+ s->con = graphic_console_init(&musicpal_gfx_ops, s);
qemu_console_resize(s->con, 128*3, 64*3);
qdev_init_gpio_in(&dev->qdev, musicpal_lcd_gpio_brigthness_in, 3);
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 891bff8..794b276 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -944,6 +944,11 @@ static void blizzard_update_display(void *opaque)
#define DEPTH 32
#include "hw/blizzard_template.h"
+static const GraphicHwOps blizzard_ops = {
+ .invalidate = blizzard_invalidate_display,
+ .gfx_update = blizzard_update_display,
+};
+
void *s1d13745_init(qemu_irq gpio_int)
{
BlizzardState *s = (BlizzardState *) g_malloc0(sizeof(*s));
@@ -951,9 +956,7 @@ void *s1d13745_init(qemu_irq gpio_int)
s->fb = g_malloc(0x180000);
- s->con = graphic_console_init(blizzard_update_display,
- blizzard_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&blizzard_ops, s);
surface = qemu_console_surface(s->con);
switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c
index 03b3245..ed7962f 100644
--- a/hw/cirrus_vga.c
+++ b/hw/cirrus_vga.c
@@ -2910,9 +2910,7 @@ static int vga_initfn(ISADevice *dev)
vga_common_init(s);
cirrus_init_common(&d->cirrus_vga, CIRRUS_ID_CLGD5430, 0,
isa_address_space(dev), isa_address_space_io(dev));
- s->con = graphic_console_init(s->update, s->invalidate,
- s->text_update,
- s);
+ s->con = graphic_console_init(s->hw_ops, s);
rom_add_vga(VGABIOS_CIRRUS_FILENAME);
/* XXX ISA-LFB support */
/* FIXME not qdev yet */
@@ -2959,9 +2957,7 @@ static int pci_cirrus_vga_initfn(PCIDevice *dev)
vga_common_init(&s->vga);
cirrus_init_common(s, device_id, 1, pci_address_space(dev),
pci_address_space_io(dev));
- s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
- s->vga.text_update,
- &s->vga);
+ s->vga.con = graphic_console_init(s->vga.hw_ops, &s->vga);
/* setup PCI */
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index 0ae5d26..af3d012 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1887,6 +1887,11 @@ static const VMStateDescription exynos4210_fimd_vmstate = {
}
};
+static const GraphicHwOps exynos4210_fimd_ops = {
+ .invalidate = exynos4210_fimd_invalidate,
+ .gfx_update = exynos4210_fimd_update,
+};
+
static int exynos4210_fimd_init(SysBusDevice *dev)
{
Exynos4210fimdState *s = FROM_SYSBUS(Exynos4210fimdState, dev);
@@ -1900,8 +1905,7 @@ static int exynos4210_fimd_init(SysBusDevice *dev)
memory_region_init_io(&s->iomem, &exynos4210_fimd_mmio_ops, s,
"exynos4210.fimd", FIMD_REGS_SIZE);
sysbus_init_mmio(dev, &s->iomem);
- s->console = graphic_console_init(exynos4210_fimd_update,
- exynos4210_fimd_invalidate, NULL, s);
+ s->console = graphic_console_init(&exynos4210_fimd_ops, s);
return 0;
}
diff --git a/hw/g364fb.c b/hw/g364fb.c
index b70fe8a..03810e9 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -475,13 +475,16 @@ static const VMStateDescription vmstate_g364fb = {
}
};
+static const GraphicHwOps g364fb_ops = {
+ .invalidate = g364fb_invalidate_display,
+ .gfx_update = g364fb_update_display,
+};
+
static void g364fb_init(DeviceState *dev, G364State *s)
{
s->vram = g_malloc0(s->vram_size);
- s->con = graphic_console_init(g364fb_update_display,
- g364fb_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&g364fb_ops, s);
memory_region_init_io(&s->mem_ctrl, &g364fb_ctrl_ops, s, "ctrl", 0x180000);
memory_region_init_ram_ptr(&s->mem_vram, "vram",
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index c027f76..6306d8c 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -254,6 +254,12 @@ static const VMStateDescription vmstate_jazz_led = {
}
};
+static const GraphicHwOps jazz_led_ops = {
+ .invalidate = jazz_led_invalidate_display,
+ .gfx_update = jazz_led_update_display,
+ .text_update = jazz_led_text_update,
+};
+
static int jazz_led_init(SysBusDevice *dev)
{
LedState *s = FROM_SYSBUS(LedState, dev);
@@ -261,9 +267,7 @@ static int jazz_led_init(SysBusDevice *dev)
memory_region_init_io(&s->iomem, &led_ops, s, "led", 1);
sysbus_init_mmio(dev, &s->iomem);
- s->con = graphic_console_init(jazz_led_update_display,
- jazz_led_invalidate_display,
- jazz_led_text_update, s);
+ s->con = graphic_console_init(&jazz_led_ops, s);
return 0;
}
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 80486e8..91c80c5 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -270,6 +270,11 @@ static void milkymist_vgafb_reset(DeviceState *d)
s->regs[R_BASEADDRESS] = 0;
}
+static const GraphicHwOps vgafb_ops = {
+ .invalidate = vgafb_invalidate_display,
+ .gfx_update = vgafb_update_display,
+};
+
static int milkymist_vgafb_init(SysBusDevice *dev)
{
MilkymistVgafbState *s = FROM_SYSBUS(typeof(*s), dev);
@@ -278,9 +283,7 @@ static int milkymist_vgafb_init(SysBusDevice *dev)
"milkymist-vgafb", R_MAX * 4);
sysbus_init_mmio(dev, &s->regs_region);
- s->con = graphic_console_init(vgafb_update_display,
- vgafb_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&vgafb_ops, s);
return 0;
}
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index 1cb49d5..eb4073b 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -384,6 +384,11 @@ void omap_lcdc_reset(struct omap_lcd_panel_s *s)
s->ctrl = 0;
}
+static const GraphicHwOps omap_ops = {
+ .invalidate = omap_invalidate_display,
+ .gfx_update = omap_update_display,
+};
+
struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
hwaddr base,
qemu_irq irq,
@@ -401,9 +406,7 @@ struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
memory_region_init_io(&s->iomem, &omap_lcdc_ops, s, "omap.lcdc", 0x100);
memory_region_add_subregion(sysmem, base, &s->iomem);
- s->con = graphic_console_init(omap_update_display,
- omap_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&omap_ops, s);
return s;
}
diff --git a/hw/pl110.c b/hw/pl110.c
index 6f24957..f80f297 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -444,6 +444,11 @@ static int vmstate_pl110_post_load(void *opaque, int version_id)
return 0;
}
+static const GraphicHwOps pl110_gfx_ops = {
+ .invalidate = pl110_invalidate_display,
+ .gfx_update = pl110_update_display,
+};
+
static int pl110_init(SysBusDevice *dev)
{
pl110_state *s = FROM_SYSBUS(pl110_state, dev);
@@ -452,9 +457,7 @@ static int pl110_init(SysBusDevice *dev)
sysbus_init_mmio(dev, &s->iomem);
sysbus_init_irq(dev, &s->irq);
qdev_init_gpio_in(&s->busdev.qdev, pl110_mux_ctrl_set, 1);
- s->con = graphic_console_init(pl110_update_display,
- pl110_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&pl110_gfx_ops, s);
return 0;
}
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 602e3dc..7d09e5e 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -991,6 +991,11 @@ static const VMStateDescription vmstate_pxa2xx_lcdc = {
#define BITS 32
#include "hw/pxa2xx_template.h"
+static const GraphicHwOps pxa2xx_ops = {
+ .invalidate = pxa2xx_invalidate_display,
+ .gfx_update = pxa2xx_update_display,
+};
+
PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
hwaddr base, qemu_irq irq)
{
@@ -1008,9 +1013,7 @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
"pxa2xx-lcd-controller", 0x00100000);
memory_region_add_subregion(sysmem, base, &s->iomem);
- s->con = graphic_console_init(pxa2xx_update_display,
- pxa2xx_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&pxa2xx_ops, s);
surface = qemu_console_surface(s->con);
switch (surface_bits_per_pixel(surface)) {
diff --git a/hw/qxl.c b/hw/qxl.c
index 0f09bae..36f18fd 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1753,7 +1753,7 @@ static void qxl_hw_update(void *opaque)
switch (qxl->mode) {
case QXL_MODE_VGA:
- vga->update(vga);
+ vga->hw_ops->gfx_update(vga);
break;
case QXL_MODE_COMPAT:
case QXL_MODE_NATIVE:
@@ -1769,7 +1769,7 @@ static void qxl_hw_invalidate(void *opaque)
PCIQXLDevice *qxl = opaque;
VGACommonState *vga = &qxl->vga;
- vga->invalidate(vga);
+ vga->hw_ops->invalidate(vga);
}
static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
@@ -1778,7 +1778,7 @@ static void qxl_hw_text_update(void *opaque, console_ch_t *chardata)
VGACommonState *vga = &qxl->vga;
if (qxl->mode == QXL_MODE_VGA) {
- vga->text_update(vga, chardata);
+ vga->hw_ops->text_update(vga, chardata);
return;
}
}
@@ -2038,6 +2038,12 @@ static int qxl_init_common(PCIQXLDevice *qxl)
return 0;
}
+static const GraphicHwOps qxl_ops = {
+ .invalidate = qxl_hw_invalidate,
+ .gfx_update = qxl_hw_update,
+ .text_update = qxl_hw_text_update,
+};
+
static int qxl_init_primary(PCIDevice *dev)
{
PCIQXLDevice *qxl = DO_UPCAST(PCIQXLDevice, pci, dev);
@@ -2054,9 +2060,7 @@ static int qxl_init_primary(PCIDevice *dev)
portio_list_init(qxl_vga_port_list, qxl_vga_portio_list, vga, "vga");
portio_list_add(qxl_vga_port_list, pci_address_space_io(dev), 0x3b0);
- vga->con = graphic_console_init(qxl_hw_update, qxl_hw_invalidate,
- qxl_hw_text_update,
- qxl);
+ vga->con = graphic_console_init(&qxl_ops, qxl);
qxl->ssd.con = vga->con,
qemu_spice_display_init_common(&qxl->ssd);
diff --git a/hw/sm501.c b/hw/sm501.c
index 1f428cd..cf3bb11 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1383,6 +1383,10 @@ static void sm501_update_display(void *opaque)
sm501_draw_crt(s);
}
+static const GraphicHwOps sm501_ops = {
+ .gfx_update = sm501_update_display,
+};
+
void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
uint32_t local_mem_bytes, qemu_irq irq, CharDriverState *chr)
{
@@ -1445,6 +1449,5 @@ void sm501_init(MemoryRegion *address_space_mem, uint32_t base,
}
/* create qemu graphic console */
- s->con = graphic_console_init(sm501_update_display, NULL,
- NULL, s);
+ s->con = graphic_console_init(&sm501_ops, s);
}
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 02feaff..9af8f75 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -284,13 +284,16 @@ static const VMStateDescription vmstate_ssd0303 = {
}
};
+static const GraphicHwOps ssd0303_ops = {
+ .invalidate = ssd0303_invalidate_display,
+ .gfx_update = ssd0303_update_display,
+};
+
static int ssd0303_init(I2CSlave *i2c)
{
ssd0303_state *s = FROM_I2C_SLAVE(ssd0303_state, i2c);
- s->con = graphic_console_init(ssd0303_update_display,
- ssd0303_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&ssd0303_ops, s);
qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY);
return 0;
}
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 301cb20..45e8dc1 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -331,15 +331,18 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
+static const GraphicHwOps ssd0323_ops = {
+ .invalidate = ssd0323_invalidate_display,
+ .gfx_update = ssd0323_update_display,
+};
+
static int ssd0323_init(SSISlave *dev)
{
ssd0323_state *s = FROM_SSI_SLAVE(ssd0323_state, dev);
s->col_end = 63;
s->row_end = 79;
- s->con = graphic_console_init(ssd0323_update_display,
- ssd0323_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&ssd0323_ops, s);
qemu_console_resize(s->con, 128 * MAGNIFY, 64 * MAGNIFY);
qdev_init_gpio_in(&dev->qdev, ssd0323_cd, 1);
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 30b624e..8eaccdb 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -548,6 +548,10 @@ static void tc6393xb_writeb(void *opaque, hwaddr addr,
(uint32_t) addr, (int)value & 0xff);
}
+static const GraphicHwOps tc6393xb_gfx_ops = {
+ .gfx_update = tc6393xb_update_display,
+};
+
TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
{
TC6393xbState *s;
@@ -583,10 +587,7 @@ TC6393xbState *tc6393xb_init(MemoryRegion *sysmem, uint32_t base, qemu_irq irq)
memory_region_add_subregion(sysmem, base + 0x100000, &s->vram);
s->scr_width = 480;
s->scr_height = 640;
- s->con = graphic_console_init(tc6393xb_update_display,
- NULL, /* invalidate */
- NULL, /* text_update */
- s);
+ s->con = graphic_console_init(&tc6393xb_gfx_ops, s);
return s;
}
diff --git a/hw/tcx.c b/hw/tcx.c
index 5d12ec4..b668071 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -511,6 +511,16 @@ static const MemoryRegionOps dummy_ops = {
},
};
+static const GraphicHwOps tcx_ops = {
+ .invalidate = tcx_invalidate_display,
+ .gfx_update = tcx_update_display,
+};
+
+static const GraphicHwOps tcx24_ops = {
+ .invalidate = tcx24_invalidate_display,
+ .gfx_update = tcx24_update_display,
+};
+
static int tcx_init1(SysBusDevice *dev)
{
TCXState *s = FROM_SYSBUS(TCXState, dev);
@@ -563,18 +573,14 @@ static int tcx_init1(SysBusDevice *dev)
&s->vram_mem, vram_offset, size);
sysbus_init_mmio(dev, &s->vram_cplane);
- s->con = graphic_console_init(tcx24_update_display,
- tcx24_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&tcx24_ops, s);
} else {
/* THC 8 bit (dummy) */
memory_region_init_io(&s->thc8, &dummy_ops, s, "tcx.thc8",
TCX_THC_NREGS_8);
sysbus_init_mmio(dev, &s->thc8);
- s->con = graphic_console_init(tcx_update_display,
- tcx_invalidate_display,
- NULL, s);
+ s->con = graphic_console_init(&tcx_ops, s);
}
qemu_console_resize(s->con, s->width, s->height);
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index d110363..20356b5 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -78,6 +78,8 @@ static void puv3_board_init(CPUUniCore32State *env, ram_addr_t ram_size)
memory_region_add_subregion(get_system_memory(), 0, ram_memory);
}
+static const GraphicHwOps no_ops;
+
static void puv3_load_kernel(const char *kernel_filename)
{
int size;
@@ -92,7 +94,7 @@ static void puv3_load_kernel(const char *kernel_filename)
}
/* cheat curses that we have a graphic console, only under ocd console */
- graphic_console_init(NULL, NULL, NULL, NULL);
+ graphic_console_init(&no_ops, NULL);
}
static void puv3_init(QEMUMachineInitArgs *args)
diff --git a/hw/vga-isa-mm.c b/hw/vga-isa-mm.c
index 5fb04fb..3f3af9a 100644
--- a/hw/vga-isa-mm.c
+++ b/hw/vga-isa-mm.c
@@ -135,9 +135,7 @@ int isa_vga_mm_init(hwaddr vram_base,
vga_common_init(&s->vga);
vga_mm_init(s, vram_base, ctrl_base, it_shift, address_space);
- s->vga.con = graphic_console_init(s->vga.update, s->vga.invalidate,
- s->vga.text_update,
- s);
+ s->vga.con = graphic_console_init(s->vga.hw_ops, s);
vga_init_vbe(&s->vga, address_space);
return 0;
diff --git a/hw/vga-isa.c b/hw/vga-isa.c
index 0a1aded..a76cef2 100644
--- a/hw/vga-isa.c
+++ b/hw/vga-isa.c
@@ -62,8 +62,7 @@ static int vga_initfn(ISADevice *dev)
isa_mem_base + 0x000a0000,
vga_io_memory, 1);
memory_region_set_coalescing(vga_io_memory);
- s->con = graphic_console_init(s->update, s->invalidate,
- s->text_update, s);
+ s->con = graphic_console_init(s->hw_ops, s);
vga_init_vbe(s, isa_address_space(dev));
/* ROM BIOS */
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index a982f2a..5ffc37b 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -150,8 +150,7 @@ static int pci_std_vga_initfn(PCIDevice *dev)
vga_common_init(s);
vga_init(s, pci_address_space(dev), pci_address_space_io(dev), true);
- s->con = graphic_console_init(s->update, s->invalidate,
- s->text_update, s);
+ s->con = graphic_console_init(s->hw_ops, s);
/* XXX: VGA_RAM_SIZE must be a power of two */
pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
diff --git a/hw/vga.c b/hw/vga.c
index a875faa..5c87754 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2250,6 +2250,12 @@ const VMStateDescription vmstate_vga_common = {
}
};
+static const GraphicHwOps vga_ops = {
+ .invalidate = vga_invalidate_display,
+ .gfx_update = vga_update_display,
+ .text_update = vga_update_text,
+};
+
void vga_common_init(VGACommonState *s)
{
int i, j, v, b;
@@ -2293,9 +2299,7 @@ void vga_common_init(VGACommonState *s)
s->get_bpp = vga_get_bpp;
s->get_offsets = vga_get_offsets;
s->get_resolution = vga_get_resolution;
- s->update = vga_update_display;
- s->invalidate = vga_invalidate_display;
- s->text_update = vga_update_text;
+ s->hw_ops = &vga_ops;
switch (vga_retrace_method) {
case VGA_RETRACE_DUMB:
s->retrace = vga_dumb_retrace;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index e4bb4a0..66f9f3c 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -152,9 +152,7 @@ typedef struct VGACommonState {
uint32_t cursor_offset;
unsigned int (*rgb_to_pixel)(unsigned int r,
unsigned int g, unsigned b);
- graphic_hw_update_ptr update;
- graphic_hw_invalidate_ptr invalidate;
- graphic_hw_text_update_ptr text_update;
+ const GraphicHwOps *hw_ops;
bool full_update_text;
bool full_update_gfx;
/* hardware mouse cursor support */
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index 4eaa69c..deb9d25 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -861,7 +861,7 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
case SVGA_REG_ENABLE:
s->enable = !!value;
s->invalidated = 1;
- s->vga.invalidate(&s->vga);
+ s->vga.hw_ops->invalidate(&s->vga);
if (s->enable && s->config) {
vga_dirty_log_stop(&s->vga);
} else {
@@ -999,7 +999,7 @@ static void vmsvga_update_display(void *opaque)
bool dirty = false;
if (!s->enable) {
- s->vga.update(&s->vga);
+ s->vga.hw_ops->gfx_update(&s->vga);
return;
}
@@ -1054,7 +1054,7 @@ static void vmsvga_invalidate_display(void *opaque)
{
struct vmsvga_state_s *s = opaque;
if (!s->enable) {
- s->vga.invalidate(&s->vga);
+ s->vga.hw_ops->invalidate(&s->vga);
return;
}
@@ -1065,8 +1065,8 @@ static void vmsvga_text_update(void *opaque, console_ch_t *chardata)
{
struct vmsvga_state_s *s = opaque;
- if (s->vga.text_update) {
- s->vga.text_update(&s->vga, chardata);
+ if (s->vga.hw_ops->text_update) {
+ s->vga.hw_ops->text_update(&s->vga, chardata);
}
}
@@ -1121,6 +1121,12 @@ static const VMStateDescription vmstate_vmware_vga = {
}
};
+static const GraphicHwOps vmsvga_ops = {
+ .invalidate = vmsvga_invalidate_display,
+ .gfx_update = vmsvga_update_display,
+ .text_update = vmsvga_text_update,
+};
+
static void vmsvga_init(struct vmsvga_state_s *s,
MemoryRegion *address_space, MemoryRegion *io)
{
@@ -1129,9 +1135,7 @@ static void vmsvga_init(struct vmsvga_state_s *s,
s->scratch_size = SVGA_SCRATCH_SIZE;
s->scratch = g_malloc(s->scratch_size * 4);
- s->vga.con = graphic_console_init(vmsvga_update_display,
- vmsvga_invalidate_display,
- vmsvga_text_update, s);
+ s->vga.con = graphic_console_init(&vmsvga_ops, s);
surface = qemu_console_surface(s->vga.con);
s->fifo_size = SVGA_FIFO_SIZE;
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 0db2f84..f2af7eb 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -977,6 +977,11 @@ struct XenDevOps xen_framebuffer_ops = {
.frontend_changed = fb_frontend_changed,
};
+static const GraphicHwOps xenfb_ops = {
+ .invalidate = xenfb_invalidate,
+ .gfx_update = xenfb_update,
+};
+
/*
* FIXME/TODO: Kill this.
* Temporary needed while DisplayState reorganization is in flight.
@@ -1004,10 +1009,7 @@ wait_more:
/* vfb */
fb = container_of(xfb, struct XenFB, c.xendev);
- fb->c.con = graphic_console_init(xenfb_update,
- xenfb_invalidate,
- NULL,
- fb);
+ fb->c.con = graphic_console_init(&xenfb_ops, fb);
fb->have_console = 1;
/* vkbd */
diff --git a/include/ui/console.h b/include/ui/console.h
index 50cd7b0..f3e7791 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -267,13 +267,13 @@ static inline void console_write_ch(console_ch_t *dest, uint32_t ch)
*dest = ch;
}
-typedef void (*graphic_hw_update_ptr)(void *);
-typedef void (*graphic_hw_invalidate_ptr)(void *);
-typedef void (*graphic_hw_text_update_ptr)(void *, console_ch_t *);
+typedef struct GraphicHwOps {
+ void (*invalidate)(void *opaque);
+ void (*gfx_update)(void *opaque);
+ void (*text_update)(void *opaque, console_ch_t *text);
+} GraphicHwOps;
-QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
- graphic_hw_invalidate_ptr invalidate,
- graphic_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(const GraphicHwOps *ops,
void *opaque);
void graphic_hw_update(QemuConsole *con);
diff --git a/ui/console.c b/ui/console.c
index c22895f..e85ecf1 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -119,9 +119,7 @@ struct QemuConsole {
DisplaySurface *surface;
/* Graphic console state. */
- graphic_hw_update_ptr hw_update;
- graphic_hw_invalidate_ptr hw_invalidate;
- graphic_hw_text_update_ptr hw_text_update;
+ const GraphicHwOps *hw_ops;
void *hw;
/* Text console state */
@@ -229,8 +227,8 @@ void graphic_hw_update(QemuConsole *con)
if (!con) {
con = active_console;
}
- if (con && con->hw_update) {
- con->hw_update(con->hw);
+ if (con && con->hw_ops->gfx_update) {
+ con->hw_ops->gfx_update(con->hw);
}
}
@@ -239,8 +237,8 @@ void graphic_hw_invalidate(QemuConsole *con)
if (!con) {
con = active_console;
}
- if (con && con->hw_invalidate) {
- con->hw_invalidate(con->hw);
+ if (con && con->hw_ops->invalidate) {
+ con->hw_ops->invalidate(con->hw);
}
}
@@ -305,8 +303,8 @@ void graphic_hw_text_update(QemuConsole *con, console_ch_t *chardata)
if (!con) {
con = active_console;
}
- if (con && con->hw_text_update)
- con->hw_text_update(con->hw, chardata);
+ if (con && con->hw_ops->text_update)
+ con->hw_ops->text_update(con->hw, chardata);
}
static void vga_fill_rect(QemuConsole *con,
@@ -1488,9 +1486,7 @@ DisplayState *init_displaystate(void)
return display_state;
}
-QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
- graphic_hw_invalidate_ptr invalidate,
- graphic_hw_text_update_ptr text_update,
+QemuConsole *graphic_console_init(const GraphicHwOps *hw_ops,
void *opaque)
{
int width = 640;
@@ -1501,9 +1497,7 @@ QemuConsole *graphic_console_init(graphic_hw_update_ptr update,
ds = get_alloc_displaystate();
trace_console_gfx_new();
s = new_console(ds, GRAPHIC_CONSOLE);
- s->hw_update = update;
- s->hw_invalidate = invalidate;
- s->hw_text_update = text_update;
+ s->hw_ops = hw_ops;
s->hw = opaque;
s->surface = qemu_create_displaysurface(width, height);
@@ -1537,6 +1531,11 @@ static void text_console_update_cursor(void *opaque)
qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
}
+static const GraphicHwOps text_console_ops = {
+ .invalidate = text_console_invalidate,
+ .text_update = text_console_update,
+};
+
static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
{
QemuConsole *s;
@@ -1568,8 +1567,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
s->cursor_timer =
qemu_new_timer_ms(rt_clock, text_console_update_cursor, s);
- s->hw_invalidate = text_console_invalidate;
- s->hw_text_update = text_console_update;
+ s->hw_ops = &text_console_ops;
s->hw = s;
/* Set text attribute defaults */
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH 15/15] console: gui timer fixes
2013-03-18 12:09 [Qemu-devel] [PATCH 00/15] console: overhaul continued Gerd Hoffmann
` (13 preceding siblings ...)
2013-03-18 12:09 ` [Qemu-devel] [PATCH 14/15] console: add GraphicHwOps Gerd Hoffmann
@ 2013-03-18 12:09 ` Gerd Hoffmann
14 siblings, 0 replies; 18+ messages in thread
From: Gerd Hoffmann @ 2013-03-18 12:09 UTC (permalink / raw)
To: qemu-devel; +Cc: Anthony Liguori, Gerd Hoffmann
Make gui update rate adaption code in gui_update() actually work.
Sprinkle in a tracepoint so you can see the code at work. Remove
the update rate adaption code in vnc and make vnc simply use the
generic bits instead.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
include/ui/console.h | 9 ++++---
trace-events | 1 +
ui/console.c | 34 ++++++++++++++++++++----
ui/sdl.c | 10 +++----
ui/vnc.c | 71 ++++++++++++++------------------------------------
ui/vnc.h | 2 --
6 files changed, 60 insertions(+), 67 deletions(-)
diff --git a/include/ui/console.h b/include/ui/console.h
index f3e7791..3cb0018 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -21,7 +21,8 @@
#define QEMU_CAPS_LOCK_LED (1 << 2)
/* in ms */
-#define GUI_REFRESH_INTERVAL 30
+#define GUI_REFRESH_INTERVAL_DEFAULT 30
+#define GUI_REFRESH_INTERVAL_IDLE 3000
typedef void QEMUPutKBDEvent(void *opaque, int keycode);
typedef void QEMUPutLEDEvent(void *opaque, int ledstate);
@@ -174,8 +175,7 @@ typedef struct DisplayChangeListenerOps {
} DisplayChangeListenerOps;
struct DisplayChangeListener {
- int idle;
- uint64_t gui_timer_interval;
+ uint64_t update_interval;
const DisplayChangeListenerOps *ops;
DisplayState *ds;
@@ -207,12 +207,13 @@ static inline int is_buffer_shared(DisplaySurface *surface)
void register_displaychangelistener(DisplayState *ds,
DisplayChangeListener *dcl);
+void update_displaychangelistener(DisplayChangeListener *dcl,
+ uint64_t interval);
void unregister_displaychangelistener(DisplayChangeListener *dcl);
void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
void dpy_gfx_replace_surface(QemuConsole *con,
DisplaySurface *surface);
-void dpy_refresh(DisplayState *s);
void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
int dst_x, int dst_y, int w, int h);
void dpy_text_cursor(QemuConsole *con, int x, int y);
diff --git a/trace-events b/trace-events
index c241985..88b1070 100644
--- a/trace-events
+++ b/trace-events
@@ -961,6 +961,7 @@ dma_map_wait(void *dbs) "dbs=%p"
console_gfx_new(void) ""
console_txt_new(int w, int h) "%dx%d"
console_select(int nr) "%d"
+console_refresh(int interval) "interval %d ms"
displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
displaysurface_create_from(void *display_surface, int w, int h, int bpp, int swap) "surface=%p, %dx%d, bpp %d, bswap %d"
displaysurface_free(void *display_surface) "surface=%p"
diff --git a/ui/console.c b/ui/console.c
index e85ecf1..7c496e9 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -157,6 +157,9 @@ struct QemuConsole {
struct DisplayState {
struct QEMUTimer *gui_timer;
+ uint64_t last_update;
+ uint64_t update_interval;
+ bool refreshing;
bool have_gfx;
bool have_text;
@@ -171,22 +174,32 @@ static int nb_consoles = 0;
static void text_console_do_init(CharDriverState *chr, DisplayState *ds);
static void dpy_gfx_switch_surface(DisplayState *ds,
DisplaySurface *surface);
+static void dpy_refresh(DisplayState *s);
static void gui_update(void *opaque)
{
- uint64_t interval = GUI_REFRESH_INTERVAL;
+ uint64_t interval = GUI_REFRESH_INTERVAL_IDLE;
+ uint64_t dcl_interval;
DisplayState *ds = opaque;
DisplayChangeListener *dcl;
+ ds->refreshing = true;
dpy_refresh(ds);
+ ds->refreshing = false;
QLIST_FOREACH(dcl, &ds->listeners, next) {
- if (dcl->gui_timer_interval &&
- dcl->gui_timer_interval < interval) {
- interval = dcl->gui_timer_interval;
+ dcl_interval = dcl->update_interval ?
+ dcl->update_interval : GUI_REFRESH_INTERVAL_DEFAULT;
+ if (interval > dcl_interval) {
+ interval = dcl_interval;
}
}
- qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
+ if (ds->update_interval != interval) {
+ ds->update_interval = interval;
+ trace_console_refresh(interval);
+ }
+ ds->last_update = qemu_get_clock_ms(rt_clock);
+ qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
}
static void gui_setup_refresh(DisplayState *ds)
@@ -1280,6 +1293,17 @@ void register_displaychangelistener(DisplayState *ds,
}
}
+void update_displaychangelistener(DisplayChangeListener *dcl,
+ uint64_t interval)
+{
+ DisplayState *ds = dcl->ds;
+
+ dcl->update_interval = interval;
+ if (!ds->refreshing && ds->update_interval > interval) {
+ qemu_mod_timer(ds->gui_timer, ds->last_update + interval);
+ }
+}
+
void unregister_displaychangelistener(DisplayChangeListener *dcl)
{
DisplayState *ds = dcl->ds;
diff --git a/ui/sdl.c b/ui/sdl.c
index ede31dc..97764a6 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -751,12 +751,12 @@ static void handle_activation(SDL_Event *ev)
if (ev->active.state & SDL_APPACTIVE) {
if (ev->active.gain) {
/* Back to default interval */
- dcl->gui_timer_interval = 0;
- dcl->idle = 0;
+ update_displaychangelistener(dcl, GUI_REFRESH_INTERVAL_DEFAULT);
} else {
- /* Sleeping interval */
- dcl->gui_timer_interval = 500;
- dcl->idle = 1;
+ /* Sleeping interval. Not using the long default here as
+ * sdl_refresh does not only update the guest screen, but
+ * also checks for gui events. */
+ update_displaychangelistener(dcl, 500);
}
}
}
diff --git a/ui/vnc.c b/ui/vnc.c
index 4c32af5..ad91a7b 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -34,9 +34,9 @@
#include "qmp-commands.h"
#include "qemu/osdep.h"
-#define VNC_REFRESH_INTERVAL_BASE 30
+#define VNC_REFRESH_INTERVAL_BASE GUI_REFRESH_INTERVAL_DEFAULT
#define VNC_REFRESH_INTERVAL_INC 50
-#define VNC_REFRESH_INTERVAL_MAX 2000
+#define VNC_REFRESH_INTERVAL_MAX GUI_REFRESH_INTERVAL_IDLE
static const struct timeval VNC_REFRESH_STATS = { 0, 500000 };
static const struct timeval VNC_REFRESH_LOSSY = { 2, 0 };
@@ -419,14 +419,12 @@ out_error:
static int vnc_update_client(VncState *vs, int has_dirty);
static int vnc_update_client_sync(VncState *vs, int has_dirty);
static void vnc_disconnect_start(VncState *vs);
-static void vnc_init_timer(VncDisplay *vd);
-static void vnc_remove_timer(VncDisplay *vd);
static void vnc_colordepth(VncState *vs);
static void framebuffer_update_request(VncState *vs, int incremental,
int x_position, int y_position,
int w, int h);
-static void vnc_refresh(void *opaque);
+static void vnc_refresh(DisplayChangeListener *dcl);
static int vnc_refresh_server_surface(VncDisplay *vd);
static void vnc_dpy_update(DisplayChangeListener *dcl,
@@ -1064,11 +1062,6 @@ void vnc_disconnect_finish(VncState *vs)
qemu_remove_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
}
- if (QTAILQ_EMPTY(&vs->vd->clients)) {
- vs->vd->dcl.idle = 1;
- }
-
- vnc_remove_timer(vs->vd);
if (vs->vd->lock_key_sync)
qemu_remove_led_event_handler(vs->led);
vnc_unlock_output(vs);
@@ -2013,9 +2006,7 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
VncDisplay *vd = vs->vd;
if (data[0] > 3) {
- vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- if (!qemu_timer_expired(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval))
- qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval);
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
}
switch (data[0]) {
@@ -2647,18 +2638,16 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
return has_dirty;
}
-static void vnc_refresh(void *opaque)
+static void vnc_refresh(DisplayChangeListener *dcl)
{
- VncDisplay *vd = opaque;
+ VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
VncState *vs, *vn;
int has_dirty, rects = 0;
graphic_hw_update(NULL);
if (vnc_trylock_display(vd)) {
- vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) +
- vd->timer_interval);
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
return;
}
@@ -2670,39 +2659,21 @@ static void vnc_refresh(void *opaque)
/* vs might be free()ed here */
}
- /* vd->timer could be NULL now if the last client disconnected,
- * in this case don't update the timer */
- if (vd->timer == NULL)
+ if (QTAILQ_EMPTY(&vd->clients)) {
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_MAX);
return;
+ }
if (has_dirty && rects) {
- vd->timer_interval /= 2;
- if (vd->timer_interval < VNC_REFRESH_INTERVAL_BASE)
- vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
+ vd->dcl.update_interval /= 2;
+ if (vd->dcl.update_interval < VNC_REFRESH_INTERVAL_BASE) {
+ vd->dcl.update_interval = VNC_REFRESH_INTERVAL_BASE;
+ }
} else {
- vd->timer_interval += VNC_REFRESH_INTERVAL_INC;
- if (vd->timer_interval > VNC_REFRESH_INTERVAL_MAX)
- vd->timer_interval = VNC_REFRESH_INTERVAL_MAX;
- }
- qemu_mod_timer(vd->timer, qemu_get_clock_ms(rt_clock) + vd->timer_interval);
-}
-
-static void vnc_init_timer(VncDisplay *vd)
-{
- vd->timer_interval = VNC_REFRESH_INTERVAL_BASE;
- if (vd->timer == NULL && !QTAILQ_EMPTY(&vd->clients)) {
- vd->timer = qemu_new_timer_ms(rt_clock, vnc_refresh, vd);
- graphic_hw_update(NULL);
- vnc_refresh(vd);
- }
-}
-
-static void vnc_remove_timer(VncDisplay *vd)
-{
- if (vd->timer != NULL && QTAILQ_EMPTY(&vd->clients)) {
- qemu_del_timer(vd->timer);
- qemu_free_timer(vd->timer);
- vd->timer = NULL;
+ vd->dcl.update_interval += VNC_REFRESH_INTERVAL_INC;
+ if (vd->dcl.update_interval > VNC_REFRESH_INTERVAL_MAX) {
+ vd->dcl.update_interval = VNC_REFRESH_INTERVAL_MAX;
+ }
}
}
@@ -2731,7 +2702,7 @@ static void vnc_connect(VncDisplay *vd, int csock, int skipauth, bool websocket)
}
VNC_DEBUG("New client on socket %d\n", csock);
- vd->dcl.idle = 0;
+ update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
socket_set_nonblock(vs->csock);
#ifdef CONFIG_VNC_WS
if (websocket) {
@@ -2787,8 +2758,6 @@ void vnc_init_state(VncState *vs)
vs->mouse_mode_notifier.notify = check_pointer_type_change;
qemu_add_mouse_mode_change_notifier(&vs->mouse_mode_notifier);
- vnc_init_timer(vd);
-
/* vs might be free()ed here */
}
@@ -2829,6 +2798,7 @@ static void vnc_listen_websocket_read(void *opaque)
static const DisplayChangeListenerOps dcl_ops = {
.dpy_name = "vnc",
+ .dpy_refresh = vnc_refresh,
.dpy_gfx_copy = vnc_dpy_copy,
.dpy_gfx_update = vnc_dpy_update,
.dpy_gfx_switch = vnc_dpy_switch,
@@ -2840,7 +2810,6 @@ void vnc_display_init(DisplayState *ds)
{
VncDisplay *vs = g_malloc0(sizeof(*vs));
- vs->dcl.idle = 1;
vnc_display = vs;
vs->lsock = -1;
diff --git a/ui/vnc.h b/ui/vnc.h
index 58e002e..ad1dec2 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -142,8 +142,6 @@ struct VncDisplay
QTAILQ_HEAD(, VncState) clients;
int num_exclusive;
VncSharePolicy share_policy;
- QEMUTimer *timer;
- int timer_interval;
int lsock;
#ifdef CONFIG_VNC_WS
int lwebsock;
--
1.7.9.7
^ permalink raw reply related [flat|nested] 18+ messages in thread