qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering
@ 2012-11-01 13:03 Gerd Hoffmann
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 01/22] console: QLIST-ify display change listeners Gerd Hoffmann
                   ` (22 more replies)
  0 siblings, 23 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Sitting on these too long already.  Series has been on the list a while
back, only splitted into two parts (separate "console cleanups" series
carrying patches 1-8).  Patch 11 was updated according to Paolos
suggestion, otherwise the patches are unmodified.

please pull,
  Gerd

The following changes since commit 286d52ebfc0d0d53c2a878e454292fea14bad41b:

  target-mips: don't flush extra TLB on permissions upgrade (2012-10-31 22:20:49 +0100)

are available in the git repository at:
  git://git.kraxel.org/qemu pixman.v3

Gerd Hoffmann (22):
      console: QLIST-ify display change listeners.
      console: add unregister_displaychangelistener
      console: move set_mouse + cursor_define callbacks
      console: s/TextConsole/QemuConsole/
      console: untangle gfx & txt updates
      console: init displaychangelisteners on register
      vga: fix text mode updating
      console: remove dpy_gfx_fill
      console: remove DisplayAllocator
      pixman: add submodule
      pixman: windup in configure & makefiles
      pixman: helper functions
      pixman: add pixman image to DisplaySurface
      console: make qemu_alloc_display static
      console: don't set PixelFormat alpha fields for 32bpp
      qxl: stop direct access to DisplaySurface fields.
      vga: stop direct access to DisplaySurface fields.
      pixman: switch screendump function.
      pixman/vnc: use pixman images in vnc.
      pixman/vnc: remove rgb_prepare_row* functions
      pixman/vnc: remove dead code.
      pixman: drop obsolete fields from DisplaySurface

 .gitmodules                   |    3 +
 Makefile                      |    9 ++
 Makefile.objs                 |    1 +
 configure                     |   38 ++++++
 console.c                     |  240 +++++++++++++++++------------------
 console.h                     |  229 ++++++++++++++++++++-------------
 hw/blizzard.c                 |    4 +-
 hw/exynos4210_fimd.c          |    2 +-
 hw/g364fb.c                   |    7 +-
 hw/jazz_led.c                 |    6 +-
 hw/milkymist-vgafb.c          |    2 +-
 hw/musicpal.c                 |    2 +-
 hw/nseries.c                  |    2 +-
 hw/omap_lcdc.c                |    2 +-
 hw/palm.c                     |    2 +-
 hw/pl110.c                    |    2 +-
 hw/pxa2xx_lcd.c               |    8 +-
 hw/qxl-render.c               |   14 +-
 hw/qxl.c                      |    4 +-
 hw/sm501.c                    |    4 +-
 hw/ssd0303.c                  |    2 +-
 hw/ssd0323.c                  |    2 +-
 hw/tc6393xb.c                 |    4 +-
 hw/tcx.c                      |   16 ++--
 hw/vga.c                      |  111 +++++++++--------
 hw/vga_int.h                  |    2 +
 hw/vmware_vga.c               |   15 ++-
 hw/xenfb.c                    |    2 +-
 pixman                        |    1 +
 qemu-common.h                 |    4 +-
 qemu-pixman.c                 |   60 +++++++++
 qemu-pixman.h                 |   32 +++++
 ui/curses.c                   |   21 +--
 ui/sdl.c                      |  140 ++------------------
 ui/spice-display.c            |    8 +-
 ui/vnc-enc-hextile-template.h |   23 ++--
 ui/vnc-enc-hextile.c          |   53 ++-------
 ui/vnc-enc-tight.c            |  280 +++++++++++++++--------------------------
 ui/vnc-enc-zrle.c             |   18 ++--
 ui/vnc-jobs.c                 |    3 +-
 ui/vnc.c                      |  255 +++++++++++++++++++------------------
 ui/vnc.h                      |   19 +++-
 vl.c                          |   49 +++++--
 43 files changed, 847 insertions(+), 854 deletions(-)
 create mode 160000 pixman
 create mode 100644 qemu-pixman.c
 create mode 100644 qemu-pixman.h

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 01/22] console: QLIST-ify display change listeners.
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
@ 2012-11-01 13:03 ` Gerd Hoffmann
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 02/22] console: add unregister_displaychangelistener Gerd Hoffmann
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.h  |   72 +++++++++++++++++++++++++++++++----------------------------
 hw/xenfb.c |    2 +-
 vl.c       |    9 ++-----
 3 files changed, 42 insertions(+), 41 deletions(-)

diff --git a/console.h b/console.h
index 6099d8d..4239eb3 100644
--- a/console.h
+++ b/console.h
@@ -164,7 +164,7 @@ struct DisplayChangeListener {
                      int w, int h, uint32_t c);
     void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 
-    struct DisplayChangeListener *next;
+    QLIST_ENTRY(DisplayChangeListener) next;
 };
 
 struct DisplayAllocator {
@@ -179,7 +179,7 @@ struct DisplayState {
     struct QEMUTimer *gui_timer;
 
     struct DisplayAllocator* allocator;
-    struct DisplayChangeListener* listeners;
+    QLIST_HEAD(, DisplayChangeListener) listeners;
 
     void (*mouse_set)(int x, int y, int on);
     void (*cursor_define)(QEMUCursor *cursor);
@@ -231,72 +231,76 @@ static inline int is_buffer_shared(DisplaySurface *surface)
 
 static inline void register_displaychangelistener(DisplayState *ds, DisplayChangeListener *dcl)
 {
-    dcl->next = ds->listeners;
-    ds->listeners = dcl;
+    QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
 }
 
 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
 {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
         dcl->dpy_update(s, x, y, w, h);
-        dcl = dcl->next;
     }
 }
 
 static inline void dpy_resize(DisplayState *s)
 {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
         dcl->dpy_resize(s);
-        dcl = dcl->next;
     }
 }
 
 static inline void dpy_setdata(DisplayState *s)
 {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_setdata) dcl->dpy_setdata(s);
-        dcl = dcl->next;
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_setdata) {
+            dcl->dpy_setdata(s);
+        }
     }
 }
 
 static inline void dpy_refresh(DisplayState *s)
 {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_refresh) dcl->dpy_refresh(s);
-        dcl = dcl->next;
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_refresh) {
+            dcl->dpy_refresh(s);
+        }
     }
 }
 
 static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
-                             int dst_x, int dst_y, int w, int h) {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_copy)
+                             int dst_x, int dst_y, int w, int h)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_copy) {
             dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
-        else /* TODO */
+        } else { /* TODO */
             dcl->dpy_update(s, dst_x, dst_y, w, h);
-        dcl = dcl->next;
+        }
     }
 }
 
 static inline void dpy_fill(struct DisplayState *s, int x, int y,
-                             int w, int h, uint32_t c) {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_fill) dcl->dpy_fill(s, x, y, w, h, c);
-        dcl = dcl->next;
+                             int w, int h, uint32_t c)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_fill) {
+            dcl->dpy_fill(s, x, y, w, h, c);
+        }
     }
 }
 
-static inline void dpy_cursor(struct DisplayState *s, int x, int y) {
-    struct DisplayChangeListener *dcl = s->listeners;
-    while (dcl != NULL) {
-        if (dcl->dpy_text_cursor) dcl->dpy_text_cursor(s, x, y);
-        dcl = dcl->next;
+static inline void dpy_cursor(struct DisplayState *s, int x, int y)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_text_cursor) {
+            dcl->dpy_text_cursor(s, x, y);
+        }
     }
 }
 
diff --git a/hw/xenfb.c b/hw/xenfb.c
index 338800a..ef24c33 100644
--- a/hw/xenfb.c
+++ b/hw/xenfb.c
@@ -717,7 +717,7 @@ static void xenfb_update(void *opaque)
 	if (xenfb_queue_full(xenfb))
 	    return;
 
-        for (l = xenfb->c.ds->listeners; l != NULL; l = l->next) {
+        QLIST_FOREACH(l, &xenfb->c.ds->listeners, next) {
             if (l->idle)
                 continue;
             idle = 0;
diff --git a/vl.c b/vl.c
index 5513d15..427e8a2 100644
--- a/vl.c
+++ b/vl.c
@@ -1359,15 +1359,14 @@ static void gui_update(void *opaque)
 {
     uint64_t interval = GUI_REFRESH_INTERVAL;
     DisplayState *ds = opaque;
-    DisplayChangeListener *dcl = ds->listeners;
+    DisplayChangeListener *dcl;
 
     dpy_refresh(ds);
 
-    while (dcl != NULL) {
+    QLIST_FOREACH(dcl, &ds->listeners, next) {
         if (dcl->gui_timer_interval &&
             dcl->gui_timer_interval < interval)
             interval = dcl->gui_timer_interval;
-        dcl = dcl->next;
     }
     qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock_ms(rt_clock));
 }
@@ -3846,14 +3845,12 @@ int main(int argc, char **argv, char **envp)
 
     /* display setup */
     dpy_resize(ds);
-    dcl = ds->listeners;
-    while (dcl != NULL) {
+    QLIST_FOREACH(dcl, &ds->listeners, next) {
         if (dcl->dpy_refresh != 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));
             break;
         }
-        dcl = dcl->next;
     }
     text_consoles_set_display(ds);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 02/22] console: add unregister_displaychangelistener
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 01/22] console: QLIST-ify display change listeners Gerd Hoffmann
@ 2012-11-01 13:03 ` Gerd Hoffmann
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 03/22] console: move set_mouse + cursor_define callbacks Gerd Hoffmann
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Also change the way the gui_timer is initialized: each time a
displaychangelistener is registered or unregistered we'll check
whether we need a timer (due to dpy_refresh callback being present)
and if so setup a timer, otherwise zap it.  This way the gui timer
works correctly with displaychangelisteners coming and going.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.h |   10 ++++++++++
 vl.c      |   31 +++++++++++++++++++++++--------
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/console.h b/console.h
index 4239eb3..f476ac8 100644
--- a/console.h
+++ b/console.h
@@ -229,9 +229,19 @@ static inline int is_buffer_shared(DisplaySurface *surface)
             !(surface->flags & QEMU_REALPIXELS_FLAG));
 }
 
+void gui_setup_refresh(DisplayState *ds);
+
 static inline void register_displaychangelistener(DisplayState *ds, DisplayChangeListener *dcl)
 {
     QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
+    gui_setup_refresh(ds);
+}
+
+static inline void unregister_displaychangelistener(DisplayState *ds,
+                                                    DisplayChangeListener *dcl)
+{
+    QLIST_REMOVE(dcl, next);
+    gui_setup_refresh(ds);
 }
 
 static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
diff --git a/vl.c b/vl.c
index 427e8a2..4c45b02 100644
--- a/vl.c
+++ b/vl.c
@@ -1371,6 +1371,29 @@ static void gui_update(void *opaque)
     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;
+
+    QLIST_FOREACH(dcl, &ds->listeners, next) {
+        if (dcl->dpy_refresh != NULL) {
+            need_timer = true;
+            break;
+        }
+    }
+
+    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;
+    }
+}
+
 struct vm_change_state_entry {
     VMChangeStateHandler *cb;
     void *opaque;
@@ -2454,7 +2477,6 @@ int main(int argc, char **argv, char **envp)
     const char *kernel_filename, *kernel_cmdline;
     char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
     DisplayState *ds;
-    DisplayChangeListener *dcl;
     int cyls, heads, secs, translation;
     QemuOpts *hda_opts = NULL, *opts, *machine_opts;
     QemuOptsList *olist;
@@ -3845,13 +3867,6 @@ int main(int argc, char **argv, char **envp)
 
     /* display setup */
     dpy_resize(ds);
-    QLIST_FOREACH(dcl, &ds->listeners, next) {
-        if (dcl->dpy_refresh != 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));
-            break;
-        }
-    }
     text_consoles_set_display(ds);
 
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 03/22] console: move set_mouse + cursor_define callbacks
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 01/22] console: QLIST-ify display change listeners Gerd Hoffmann
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 02/22] console: add unregister_displaychangelistener Gerd Hoffmann
@ 2012-11-01 13:03 ` Gerd Hoffmann
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 04/22] console: s/TextConsole/QemuConsole/ Gerd Hoffmann
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

When adding DisplayChangeListeners the set_mouse and cursor_define
callbacks have been left in DisplayState for some reason.  Fix it.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c          |    2 +-
 console.h          |   39 +++++++++++++++++++++++++++++++++++----
 hw/jazz_led.c      |    2 +-
 hw/qxl-render.c    |    2 +-
 hw/vga.c           |   10 +++++-----
 hw/vmware_vga.c    |   11 ++++++-----
 ui/sdl.c           |    8 ++++----
 ui/spice-display.c |    4 ++--
 ui/vnc.c           |    8 ++++----
 9 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/console.c b/console.c
index 3f3d254..260a029 100644
--- a/console.c
+++ b/console.c
@@ -1242,7 +1242,7 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
         s->text_y[1] = 0;
     }
     if (s->cursor_invalidate) {
-        dpy_cursor(s->ds, s->x, s->y);
+        dpy_text_cursor(s->ds, s->x, s->y);
         s->cursor_invalidate = 0;
     }
 }
diff --git a/console.h b/console.h
index f476ac8..fb38ce9 100644
--- a/console.h
+++ b/console.h
@@ -164,6 +164,9 @@ struct DisplayChangeListener {
                      int w, int h, uint32_t c);
     void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
 
+    void (*dpy_mouse_set)(struct DisplayState *s, int x, int y, int on);
+    void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
+
     QLIST_ENTRY(DisplayChangeListener) next;
 };
 
@@ -181,9 +184,6 @@ struct DisplayState {
     struct DisplayAllocator* allocator;
     QLIST_HEAD(, DisplayChangeListener) listeners;
 
-    void (*mouse_set)(int x, int y, int on);
-    void (*cursor_define)(QEMUCursor *cursor);
-
     struct DisplayState *next;
 };
 
@@ -304,7 +304,7 @@ static inline void dpy_fill(struct DisplayState *s, int x, int y,
     }
 }
 
-static inline void dpy_cursor(struct DisplayState *s, int x, int y)
+static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
@@ -314,6 +314,37 @@ static inline void dpy_cursor(struct DisplayState *s, int x, int y)
     }
 }
 
+static inline void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_mouse_set) {
+            dcl->dpy_mouse_set(s, x, y, on);
+        }
+    }
+}
+
+static inline void dpy_cursor_define(struct DisplayState *s, QEMUCursor *cursor)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_cursor_define) {
+            dcl->dpy_cursor_define(s, cursor);
+        }
+    }
+}
+
+static inline bool dpy_cursor_define_supported(struct DisplayState *s)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_cursor_define) {
+            return true;
+        }
+    }
+    return false;
+}
+
 static inline int ds_get_linesize(DisplayState *ds)
 {
     return ds->surface->linesize;
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index a6a90ab..853bf6d 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -210,7 +210,7 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
     LedState *s = opaque;
     char buf[2];
 
-    dpy_cursor(s->ds, -1, -1);
+    dpy_text_cursor(s->ds, -1, -1);
     qemu_console_resize(s->ds, 2, 1);
 
     /* TODO: draw the segments */
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index b66c168..e8cf29e 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -234,7 +234,7 @@ int qxl_render_cursor(PCIQXLDevice *qxl, QXLCommandExt *ext)
         return 1;
     }
 
-    if (!qxl->ssd.ds->mouse_set || !qxl->ssd.ds->cursor_define) {
+    if (!dpy_cursor_define_supported(qxl->ssd.ds)) {
         return 0;
     }
 
diff --git a/hw/vga.c b/hw/vga.c
index e4220df..f3256cb 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2070,11 +2070,11 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             s->cr[VGA_CRTC_CURSOR_END] != s->cursor_end || full_update) {
             cursor_visible = !(s->cr[VGA_CRTC_CURSOR_START] & 0x20);
             if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
-                dpy_cursor(s->ds,
-                           TEXTMODE_X(cursor_offset),
-                           TEXTMODE_Y(cursor_offset));
+                dpy_text_cursor(s->ds,
+                                TEXTMODE_X(cursor_offset),
+                                TEXTMODE_Y(cursor_offset));
             else
-                dpy_cursor(s->ds, -1, -1);
+                dpy_text_cursor(s->ds, -1, -1);
             s->cursor_offset = cursor_offset;
             s->cursor_start = s->cr[VGA_CRTC_CURSOR_START];
             s->cursor_end = s->cr[VGA_CRTC_CURSOR_END];
@@ -2135,7 +2135,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
     /* Display a message */
     s->last_width = 60;
     s->last_height = height = 3;
-    dpy_cursor(s->ds, -1, -1);
+    dpy_text_cursor(s->ds, -1, -1);
     s->ds->surface->width = s->last_width;
     s->ds->surface->height = height;
     dpy_resize(s->ds);
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index badaf7c..dc92790 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -478,8 +478,7 @@ static inline void vmsvga_cursor_define(struct vmsvga_state_s *s,
         qc = cursor_builtin_left_ptr();
     }
 
-    if (s->vga.ds->cursor_define)
-        s->vga.ds->cursor_define(qc);
+    dpy_cursor_define(s->vga.ds, qc);
     cursor_put(qc);
 }
 #endif
@@ -754,9 +753,10 @@ static uint32_t vmsvga_value_read(void *opaque, uint32_t address)
         caps |= SVGA_CAP_RECT_FILL;
 #endif
 #ifdef HW_MOUSE_ACCEL
-        if (s->vga.ds->mouse_set)
+        if (dpy_cursor_define_supported(s->vga.ds)) {
             caps |= SVGA_CAP_CURSOR | SVGA_CAP_CURSOR_BYPASS_2 |
                     SVGA_CAP_CURSOR_BYPASS;
+        }
 #endif
         return caps;
 
@@ -903,8 +903,9 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
         s->cursor.on |= (value == SVGA_CURSOR_ON_SHOW);
         s->cursor.on &= (value != SVGA_CURSOR_ON_HIDE);
 #ifdef HW_MOUSE_ACCEL
-        if (s->vga.ds->mouse_set && value <= SVGA_CURSOR_ON_SHOW)
-            s->vga.ds->mouse_set(s->cursor.x, s->cursor.y, s->cursor.on);
+        if (value <= SVGA_CURSOR_ON_SHOW) {
+            dpy_mouse_set(s->vga.ds, s->cursor.x, s->cursor.y, s->cursor.on);
+        }
 #endif
         break;
 
diff --git a/ui/sdl.c b/ui/sdl.c
index f6f711c..f8ead93 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -905,7 +905,7 @@ static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
     SDL_FillRect(real_screen, &dst, c);
 }
 
-static void sdl_mouse_warp(int x, int y, int on)
+static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
 {
     if (on) {
         if (!guest_cursor)
@@ -921,7 +921,7 @@ static void sdl_mouse_warp(int x, int y, int on)
     guest_x = x, guest_y = y;
 }
 
-static void sdl_mouse_define(QEMUCursor *c)
+static void sdl_mouse_define(DisplayState *ds, QEMUCursor *c)
 {
     uint8_t *image, *mask;
     int bpl;
@@ -1025,8 +1025,8 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     dcl->dpy_refresh = sdl_refresh;
     dcl->dpy_setdata = sdl_setdata;
     dcl->dpy_fill = sdl_fill;
-    ds->mouse_set = sdl_mouse_warp;
-    ds->cursor_define = sdl_mouse_define;
+    dcl->dpy_mouse_set = sdl_mouse_warp;
+    dcl->dpy_cursor_define = sdl_mouse_define;
     register_displaychangelistener(ds, dcl);
 
     da = g_malloc0(sizeof(DisplayAllocator));
diff --git a/ui/spice-display.c b/ui/spice-display.c
index b61764f..5779fa8 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -404,12 +404,12 @@ void qemu_spice_display_resize(SimpleSpiceDisplay *ssd)
 void qemu_spice_cursor_refresh_unlocked(SimpleSpiceDisplay *ssd)
 {
     if (ssd->cursor) {
-        ssd->ds->cursor_define(ssd->cursor);
+        dpy_cursor_define(ssd->ds, ssd->cursor);
         cursor_put(ssd->cursor);
         ssd->cursor = NULL;
     }
     if (ssd->mouse_x != -1 && ssd->mouse_y != -1) {
-        ssd->ds->mouse_set(ssd->mouse_x, ssd->mouse_y, 1);
+        dpy_mouse_set(ssd->ds, ssd->mouse_x, ssd->mouse_y, 1);
         ssd->mouse_x = -1;
         ssd->mouse_y = -1;
     }
diff --git a/ui/vnc.c b/ui/vnc.c
index d0ffcc5..1b70db7 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -802,7 +802,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
     }
 }
 
-static void vnc_mouse_set(int x, int y, int visible)
+static void vnc_mouse_set(DisplayState *ds, int x, int y, int visible)
 {
     /* can we ask the client(s) to move the pointer ??? */
 }
@@ -829,7 +829,7 @@ static int vnc_cursor_define(VncState *vs)
     return -1;
 }
 
-static void vnc_dpy_cursor_define(QEMUCursor *c)
+static void vnc_dpy_cursor_define(DisplayState *ds, QEMUCursor *c)
 {
     VncDisplay *vd = vnc_display;
     VncState *vs;
@@ -2757,9 +2757,9 @@ void vnc_display_init(DisplayState *ds)
     dcl->dpy_update = vnc_dpy_update;
     dcl->dpy_resize = vnc_dpy_resize;
     dcl->dpy_setdata = vnc_dpy_setdata;
+    dcl->dpy_mouse_set = vnc_mouse_set;
+    dcl->dpy_cursor_define = vnc_dpy_cursor_define;
     register_displaychangelistener(ds, dcl);
-    ds->mouse_set = vnc_mouse_set;
-    ds->cursor_define = vnc_dpy_cursor_define;
 }
 
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 04/22] console: s/TextConsole/QemuConsole/
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 03/22] console: move set_mouse + cursor_define callbacks Gerd Hoffmann
@ 2012-11-01 13:03 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 05/22] console: untangle gfx & txt updates Gerd Hoffmann
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:03 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c     |   72 ++++++++++++++++++++++++++++----------------------------
 qemu-common.h |    3 +-
 2 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/console.c b/console.c
index 260a029..b53dc1b 100644
--- a/console.c
+++ b/console.c
@@ -114,20 +114,20 @@ typedef enum {
     TEXT_CONSOLE_FIXED_SIZE
 } console_type_t;
 
-/* ??? This is mis-named.
-   It is used for both text and graphical consoles.  */
-struct TextConsole {
+struct QemuConsole {
     int index;
     console_type_t console_type;
     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;
     void *hw;
-
     int g_width, g_height;
+
+    /* Text console state */
     int width;
     int height;
     int total_height;
@@ -161,8 +161,8 @@ struct TextConsole {
 };
 
 static DisplayState *display_state;
-static TextConsole *active_console;
-static TextConsole *consoles[MAX_CONSOLES];
+static QemuConsole *active_console;
+static QemuConsole *consoles[MAX_CONSOLES];
 static int nb_consoles = 0;
 
 void vga_hw_update(void)
@@ -179,7 +179,7 @@ void vga_hw_invalidate(void)
 
 void qmp_screendump(const char *filename, Error **errp)
 {
-    TextConsole *previous_active_console;
+    QemuConsole *previous_active_console;
     bool cswitch;
 
     previous_active_console = active_console;
@@ -521,7 +521,7 @@ static void vga_putcharxy(DisplayState *ds, int x, int y, int ch,
     }
 }
 
-static void text_console_resize(TextConsole *s)
+static void text_console_resize(QemuConsole *s)
 {
     TextCell *cells, *c, *c1;
     int w1, x, y, last_width;
@@ -553,7 +553,7 @@ static void text_console_resize(TextConsole *s)
     s->cells = cells;
 }
 
-static inline void text_update_xy(TextConsole *s, int x, int y)
+static inline void text_update_xy(QemuConsole *s, int x, int y)
 {
     s->text_x[0] = MIN(s->text_x[0], x);
     s->text_x[1] = MAX(s->text_x[1], x);
@@ -561,7 +561,7 @@ static inline void text_update_xy(TextConsole *s, int x, int y)
     s->text_y[1] = MAX(s->text_y[1], y);
 }
 
-static void invalidate_xy(TextConsole *s, int x, int y)
+static void invalidate_xy(QemuConsole *s, int x, int y)
 {
     if (s->update_x0 > x * FONT_WIDTH)
         s->update_x0 = x * FONT_WIDTH;
@@ -573,7 +573,7 @@ static void invalidate_xy(TextConsole *s, int x, int y)
         s->update_y1 = (y + 1) * FONT_HEIGHT;
 }
 
-static void update_xy(TextConsole *s, int x, int y)
+static void update_xy(QemuConsole *s, int x, int y)
 {
     TextCell *c;
     int y1, y2;
@@ -597,7 +597,7 @@ static void update_xy(TextConsole *s, int x, int y)
     }
 }
 
-static void console_show_cursor(TextConsole *s, int show)
+static void console_show_cursor(QemuConsole *s, int show)
 {
     TextCell *c;
     int y, y1;
@@ -631,7 +631,7 @@ static void console_show_cursor(TextConsole *s, int show)
     }
 }
 
-static void console_refresh(TextConsole *s)
+static void console_refresh(QemuConsole *s)
 {
     TextCell *c;
     int x, y, y1;
@@ -666,7 +666,7 @@ static void console_refresh(TextConsole *s)
 
 static void console_scroll(int ydelta)
 {
-    TextConsole *s;
+    QemuConsole *s;
     int i, y1;
 
     s = active_console;
@@ -698,7 +698,7 @@ static void console_scroll(int ydelta)
     console_refresh(s);
 }
 
-static void console_put_lf(TextConsole *s)
+static void console_put_lf(QemuConsole *s)
 {
     TextCell *c;
     int x, y1;
@@ -749,7 +749,7 @@ static void console_put_lf(TextConsole *s)
  * NOTE: I know this code is not very efficient (checking every color for it
  * self) but it is more readable and better maintainable.
  */
-static void console_handle_escape(TextConsole *s)
+static void console_handle_escape(QemuConsole *s)
 {
     int i;
 
@@ -842,7 +842,7 @@ static void console_handle_escape(TextConsole *s)
     }
 }
 
-static void console_clear_xy(TextConsole *s, int x, int y)
+static void console_clear_xy(QemuConsole *s, int x, int y)
 {
     int y1 = (s->y_base + y) % s->total_height;
     TextCell *c = &s->cells[y1 * s->width + x];
@@ -852,7 +852,7 @@ static void console_clear_xy(TextConsole *s, int x, int y)
 }
 
 /* set cursor, checking bounds */
-static void set_cursor(TextConsole *s, int x, int y)
+static void set_cursor(QemuConsole *s, int x, int y)
 {
     if (x < 0) {
         x = 0;
@@ -871,7 +871,7 @@ static void set_cursor(TextConsole *s, int x, int y)
     s->y = y;
 }
 
-static void console_putchar(TextConsole *s, int ch)
+static void console_putchar(QemuConsole *s, int ch)
 {
     TextCell *c;
     int y1, i;
@@ -1078,7 +1078,7 @@ static void console_putchar(TextConsole *s, int ch)
 
 void console_select(unsigned int index)
 {
-    TextConsole *s;
+    QemuConsole *s;
 
     if (index >= MAX_CONSOLES)
         return;
@@ -1111,7 +1111,7 @@ void console_select(unsigned int index)
 
 static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
 {
-    TextConsole *s = chr->opaque;
+    QemuConsole *s = chr->opaque;
     int i;
 
     s->update_x0 = s->width * FONT_WIDTH;
@@ -1133,7 +1133,7 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
 
 static void kbd_send_chars(void *opaque)
 {
-    TextConsole *s = opaque;
+    QemuConsole *s = opaque;
     int len;
     uint8_t buf[16];
 
@@ -1156,7 +1156,7 @@ static void kbd_send_chars(void *opaque)
 /* called when an ascii key is pressed */
 void kbd_put_keysym(int keysym)
 {
-    TextConsole *s;
+    QemuConsole *s;
     uint8_t buf[16], *q;
     int c;
 
@@ -1211,7 +1211,7 @@ void kbd_put_keysym(int keysym)
 
 static void text_console_invalidate(void *opaque)
 {
-    TextConsole *s = (TextConsole *) opaque;
+    QemuConsole *s = (QemuConsole *) opaque;
     if (!ds_get_bits_per_pixel(s->ds) && s->console_type == TEXT_CONSOLE) {
         s->g_width = ds_get_width(s->ds);
         s->g_height = ds_get_height(s->ds);
@@ -1222,7 +1222,7 @@ static void text_console_invalidate(void *opaque)
 
 static void text_console_update(void *opaque, console_ch_t *chardata)
 {
-    TextConsole *s = (TextConsole *) opaque;
+    QemuConsole *s = (QemuConsole *) opaque;
     int i, j, src;
 
     if (s->text_x[0] <= s->text_x[1]) {
@@ -1247,10 +1247,10 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
     }
 }
 
-static TextConsole *get_graphic_console(DisplayState *ds)
+static QemuConsole *get_graphic_console(DisplayState *ds)
 {
     int i;
-    TextConsole *s;
+    QemuConsole *s;
     for (i = 0; i < nb_consoles; i++) {
         s = consoles[i];
         if (s->console_type == GRAPHIC_CONSOLE && s->ds == ds)
@@ -1259,14 +1259,14 @@ static TextConsole *get_graphic_console(DisplayState *ds)
     return NULL;
 }
 
-static TextConsole *new_console(DisplayState *ds, console_type_t console_type)
+static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
 {
-    TextConsole *s;
+    QemuConsole *s;
     int i;
 
     if (nb_consoles >= MAX_CONSOLES)
         return NULL;
-    s = g_malloc0(sizeof(TextConsole));
+    s = g_malloc0(sizeof(QemuConsole));
     if (!active_console || ((active_console->console_type != GRAPHIC_CONSOLE) &&
         (console_type == GRAPHIC_CONSOLE))) {
         active_console = s;
@@ -1417,7 +1417,7 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update,
                                    vga_hw_text_update_ptr text_update,
                                    void *opaque)
 {
-    TextConsole *s;
+    QemuConsole *s;
     DisplayState *ds;
 
     ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
@@ -1463,14 +1463,14 @@ void console_color_init(DisplayState *ds)
 
 static void text_console_set_echo(CharDriverState *chr, bool echo)
 {
-    TextConsole *s = chr->opaque;
+    QemuConsole *s = chr->opaque;
 
     s->echo = echo;
 }
 
 static void text_console_update_cursor(void *opaque)
 {
-    TextConsole *s = opaque;
+    QemuConsole *s = opaque;
 
     s->cursor_visible_phase = !s->cursor_visible_phase;
     vga_hw_invalidate();
@@ -1480,7 +1480,7 @@ static void text_console_update_cursor(void *opaque)
 
 static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 {
-    TextConsole *s;
+    QemuConsole *s;
     static int color_inited;
 
     s = chr->opaque;
@@ -1543,7 +1543,7 @@ static void text_console_do_init(CharDriverState *chr, DisplayState *ds)
 CharDriverState *text_console_init(QemuOpts *opts)
 {
     CharDriverState *chr;
-    TextConsole *s;
+    QemuConsole *s;
     unsigned width;
     unsigned height;
 
@@ -1589,7 +1589,7 @@ void text_consoles_set_display(DisplayState *ds)
 
 void qemu_console_resize(DisplayState *ds, int width, int height)
 {
-    TextConsole *s = get_graphic_console(ds);
+    QemuConsole *s = get_graphic_console(ds);
     if (!s) return;
 
     s->g_width = width;
diff --git a/qemu-common.h b/qemu-common.h
index b54612b..fdd0dbc 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -264,8 +264,7 @@ typedef struct DisplayChangeListener DisplayChangeListener;
 typedef struct DisplaySurface DisplaySurface;
 typedef struct DisplayAllocator DisplayAllocator;
 typedef struct PixelFormat PixelFormat;
-typedef struct TextConsole TextConsole;
-typedef TextConsole QEMUConsole;
+typedef struct QemuConsole QemuConsole;
 typedef struct CharDriverState CharDriverState;
 typedef struct MACAddr MACAddr;
 typedef struct NetClientState NetClientState;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 05/22] console: untangle gfx & txt updates
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2012-11-01 13:03 ` [Qemu-devel] [PATCH 04/22] console: s/TextConsole/QemuConsole/ Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-02  7:20   ` Jan Kiszka
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 06/22] console: init displaychangelisteners on register Gerd Hoffmann
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

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

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

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

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

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c            |   59 +++++++++++++++++++++-------------------
 console.h            |   74 +++++++++++++++++++++++++++++++++++---------------
 hw/blizzard.c        |    4 +-
 hw/exynos4210_fimd.c |    2 +-
 hw/g364fb.c          |    7 +++--
 hw/jazz_led.c        |    4 +-
 hw/milkymist-vgafb.c |    2 +-
 hw/musicpal.c        |    2 +-
 hw/nseries.c         |    2 +-
 hw/omap_lcdc.c       |    2 +-
 hw/palm.c            |    2 +-
 hw/pl110.c           |    2 +-
 hw/pxa2xx_lcd.c      |    8 +++---
 hw/qxl-render.c      |   10 +++---
 hw/qxl.c             |    4 +-
 hw/sm501.c           |    4 +-
 hw/ssd0303.c         |    2 +-
 hw/ssd0323.c         |    2 +-
 hw/tc6393xb.c        |    4 +-
 hw/tcx.c             |   16 +++++-----
 hw/vga.c             |   34 ++++++++++-------------
 hw/vmware_vga.c      |    4 +-
 ui/curses.c          |   21 +++++---------
 ui/sdl.c             |   12 ++++----
 ui/spice-display.c   |    4 +-
 ui/vnc.c             |    8 +++---
 vl.c                 |   14 ++++++++-
 27 files changed, 171 insertions(+), 138 deletions(-)

diff --git a/console.c b/console.c
index b53dc1b..61812c7 100644
--- a/console.c
+++ b/console.c
@@ -638,30 +638,33 @@ static void console_refresh(QemuConsole *s)
 
     if (s != active_console)
         return;
-    if (!ds_get_bits_per_pixel(s->ds)) {
+
+    if (s->ds->have_text) {
         s->text_x[0] = 0;
         s->text_y[0] = 0;
         s->text_x[1] = s->width - 1;
         s->text_y[1] = s->height - 1;
         s->cursor_invalidate = 1;
-        return;
     }
 
-    vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
-                  color_table[0][COLOR_BLACK]);
-    y1 = s->y_displayed;
-    for(y = 0; y < s->height; y++) {
-        c = s->cells + y1 * s->width;
-        for(x = 0; x < s->width; x++) {
-            vga_putcharxy(s->ds, x, y, c->ch,
-                          &(c->t_attrib));
-            c++;
+    if (s->ds->have_gfx) {
+        vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
+                      color_table[0][COLOR_BLACK]);
+        y1 = s->y_displayed;
+        for (y = 0; y < s->height; y++) {
+            c = s->cells + y1 * s->width;
+            for (x = 0; x < s->width; x++) {
+                vga_putcharxy(s->ds, x, y, c->ch,
+                              &(c->t_attrib));
+                c++;
+            }
+            if (++y1 == s->total_height) {
+                y1 = 0;
+            }
         }
-        if (++y1 == s->total_height)
-            y1 = 0;
+        console_show_cursor(s, 1);
+        dpy_gfx_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
     }
-    console_show_cursor(s, 1);
-    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
 }
 
 static void console_scroll(int ydelta)
@@ -1094,17 +1097,17 @@ void console_select(unsigned int index)
             qemu_del_timer(active_console->cursor_timer);
         }
         active_console = s;
-        if (ds_get_bits_per_pixel(s->ds)) {
+        if (ds->have_gfx) {
             ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
-        } else {
-            s->ds->surface->width = s->width;
-            s->ds->surface->height = s->height;
+            dpy_gfx_resize(ds);
+        }
+        if (ds->have_text) {
+            dpy_text_resize(ds, s->width, s->height);
         }
         if (s->cursor_timer) {
             qemu_mod_timer(s->cursor_timer,
                    qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
         }
-        dpy_resize(s->ds);
         vga_hw_invalidate();
     }
 }
@@ -1123,10 +1126,10 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
         console_putchar(s, buf[i]);
     }
     console_show_cursor(s, 1);
-    if (ds_get_bits_per_pixel(s->ds) && s->update_x0 < s->update_x1) {
-        dpy_update(s->ds, s->update_x0, s->update_y0,
-                   s->update_x1 - s->update_x0,
-                   s->update_y1 - s->update_y0);
+    if (s->ds->have_gfx && s->update_x0 < s->update_x1) {
+        dpy_gfx_update(s->ds, s->update_x0, s->update_y0,
+                       s->update_x1 - s->update_x0,
+                       s->update_y1 - s->update_y0);
     }
     return len;
 }
@@ -1234,8 +1237,8 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
                                 (s->cells[src].t_attrib.fgcol << 12) |
                                 (s->cells[src].t_attrib.bgcol << 8) |
                                 (s->cells[src].t_attrib.bold << 21));
-        dpy_update(s->ds, s->text_x[0], s->text_y[0],
-                   s->text_x[1] - s->text_x[0], i - s->text_y[0]);
+        dpy_text_update(s->ds, s->text_x[0], s->text_y[0],
+                        s->text_x[1] - s->text_x[0], i - s->text_y[0]);
         s->text_x[0] = s->width;
         s->text_y[0] = s->height;
         s->text_x[1] = 0;
@@ -1596,7 +1599,7 @@ void qemu_console_resize(DisplayState *ds, int width, int height)
     s->g_height = height;
     if (is_graphic_console()) {
         ds->surface = qemu_resize_displaysurface(ds, width, height);
-        dpy_resize(ds);
+        dpy_gfx_resize(ds);
     }
 }
 
@@ -1604,7 +1607,7 @@ void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
                        int dst_x, int dst_y, int w, int h)
 {
     if (is_graphic_console()) {
-        dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
+        dpy_gfx_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
     }
 }
 
diff --git a/console.h b/console.h
index fb38ce9..00e2f03 100644
--- a/console.h
+++ b/console.h
@@ -154,15 +154,19 @@ struct DisplayChangeListener {
     int idle;
     uint64_t gui_timer_interval;
 
-    void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
-    void (*dpy_resize)(struct DisplayState *s);
-    void (*dpy_setdata)(struct DisplayState *s);
     void (*dpy_refresh)(struct DisplayState *s);
-    void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
-                     int dst_x, int dst_y, int w, int h);
-    void (*dpy_fill)(struct DisplayState *s, int x, int y,
-                     int w, int h, uint32_t c);
+
+    void (*dpy_gfx_update)(struct DisplayState *s, int x, int y, int w, int h);
+    void (*dpy_gfx_resize)(struct DisplayState *s);
+    void (*dpy_gfx_setdata)(struct DisplayState *s);
+    void (*dpy_gfx_copy)(struct DisplayState *s, int src_x, int src_y,
+                         int dst_x, int dst_y, int w, int h);
+    void (*dpy_gfx_fill)(struct DisplayState *s, int x, int y,
+                         int w, int h, uint32_t c);
+
     void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
+    void (*dpy_text_resize)(struct DisplayState *s, int w, int h);
+    void (*dpy_text_update)(struct DisplayState *s, int x, int y, int w, int h);
 
     void (*dpy_mouse_set)(struct DisplayState *s, int x, int y, int on);
     void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
@@ -180,6 +184,8 @@ struct DisplayState {
     struct DisplaySurface *surface;
     void *opaque;
     struct QEMUTimer *gui_timer;
+    bool have_gfx;
+    bool have_text;
 
     struct DisplayAllocator* allocator;
     QLIST_HEAD(, DisplayChangeListener) listeners;
@@ -244,28 +250,32 @@ static inline void unregister_displaychangelistener(DisplayState *ds,
     gui_setup_refresh(ds);
 }
 
-static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
+static inline void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        dcl->dpy_update(s, x, y, w, h);
+        if (dcl->dpy_gfx_update) {
+            dcl->dpy_gfx_update(s, x, y, w, h);
+        }
     }
 }
 
-static inline void dpy_resize(DisplayState *s)
+static inline void dpy_gfx_resize(DisplayState *s)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        dcl->dpy_resize(s);
+        if (dcl->dpy_gfx_resize) {
+            dcl->dpy_gfx_resize(s);
+        }
     }
 }
 
-static inline void dpy_setdata(DisplayState *s)
+static inline void dpy_gfx_setdata(DisplayState *s)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        if (dcl->dpy_setdata) {
-            dcl->dpy_setdata(s);
+        if (dcl->dpy_gfx_setdata) {
+            dcl->dpy_gfx_setdata(s);
         }
     }
 }
@@ -280,26 +290,26 @@ static inline void dpy_refresh(DisplayState *s)
     }
 }
 
-static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
+static inline void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
                              int dst_x, int dst_y, int w, int h)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        if (dcl->dpy_copy) {
-            dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
+        if (dcl->dpy_gfx_copy) {
+            dcl->dpy_gfx_copy(s, src_x, src_y, dst_x, dst_y, w, h);
         } else { /* TODO */
-            dcl->dpy_update(s, dst_x, dst_y, w, h);
+            dcl->dpy_gfx_update(s, dst_x, dst_y, w, h);
         }
     }
 }
 
-static inline void dpy_fill(struct DisplayState *s, int x, int y,
-                             int w, int h, uint32_t c)
+static inline void dpy_gfx_fill(struct DisplayState *s, int x, int y,
+                                int w, int h, uint32_t c)
 {
     struct DisplayChangeListener *dcl;
     QLIST_FOREACH(dcl, &s->listeners, next) {
-        if (dcl->dpy_fill) {
-            dcl->dpy_fill(s, x, y, w, h, c);
+        if (dcl->dpy_gfx_fill) {
+            dcl->dpy_gfx_fill(s, x, y, w, h, c);
         }
     }
 }
@@ -314,6 +324,26 @@ static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
     }
 }
 
+static inline void dpy_text_update(DisplayState *s, int x, int y, int w, int h)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_text_update) {
+            dcl->dpy_text_update(s, x, y, w, h);
+        }
+    }
+}
+
+static inline void dpy_text_resize(DisplayState *s, int w, int h)
+{
+    struct DisplayChangeListener *dcl;
+    QLIST_FOREACH(dcl, &s->listeners, next) {
+        if (dcl->dpy_text_resize) {
+            dcl->dpy_text_resize(s, w, h);
+        }
+    }
+}
+
 static inline void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
 {
     struct DisplayChangeListener *dcl;
diff --git a/hw/blizzard.c b/hw/blizzard.c
index 06e19b3..1b57eb5 100644
--- a/hw/blizzard.c
+++ b/hw/blizzard.c
@@ -921,8 +921,8 @@ static void blizzard_update_display(void *opaque)
     for (; y < s->my[1]; y ++, src += bypl, dst += bypl)
         memcpy(dst, src, bwidth);
 
-    dpy_update(s->state, s->mx[0], s->my[0],
-                    s->mx[1] - s->mx[0], y - s->my[0]);
+    dpy_gfx_update(s->state, s->mx[0], s->my[0],
+                   s->mx[1] - s->mx[0], y - s->my[0]);
 
     s->mx[0] = s->x;
     s->mx[1] = 0;
diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
index 7cb2c31..f2443ca 100644
--- a/hw/exynos4210_fimd.c
+++ b/hw/exynos4210_fimd.c
@@ -1307,7 +1307,7 @@ static void exynos4210_fimd_update(void *opaque)
             fimd_copy_line_toqemu(global_width, s->ifb + global_width * line *
                     RGBA_SIZE, d + global_width * line * bpp);
         }
-        dpy_update(s->console, 0, 0, global_width, global_height);
+        dpy_gfx_update(s->console, 0, 0, global_width, global_height);
     }
     s->invalidate = false;
     s->vidintcon[1] |= FIMD_VIDINT_INTFRMPEND;
diff --git a/hw/g364fb.c b/hw/g364fb.c
index f7b4bf5..8192baf 100644
--- a/hw/g364fb.c
+++ b/hw/g364fb.c
@@ -197,7 +197,8 @@ static void g364fb_draw_graphic8(G364State *s)
                 reset_dirty(s, page_min, page_max);
                 page_min = (ram_addr_t)-1;
                 page_max = 0;
-                dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
+                dpy_gfx_update(s->ds, xmin, ymin,
+                               xmax - xmin + 1, ymax - ymin + 1);
                 xmin = s->width;
                 xmax = 0;
                 ymin = s->height;
@@ -216,7 +217,7 @@ static void g364fb_draw_graphic8(G364State *s)
 
 done:
     if (page_min != (ram_addr_t)-1) {
-        dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
+        dpy_gfx_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
         reset_dirty(s, page_min, page_max);
     }
 }
@@ -238,7 +239,7 @@ static void g364fb_draw_blank(G364State *s)
         d += ds_get_linesize(s->ds);
     }
 
-    dpy_update(s->ds, 0, 0, s->width, s->height);
+    dpy_gfx_update(s->ds, 0, 0, s->width, s->height);
     s->blanked = 1;
 }
 
diff --git a/hw/jazz_led.c b/hw/jazz_led.c
index 853bf6d..640e75e 100644
--- a/hw/jazz_led.c
+++ b/hw/jazz_led.c
@@ -196,7 +196,7 @@ static void jazz_led_update_display(void *opaque)
     }
 
     s->state = REDRAW_NONE;
-    dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
+    dpy_gfx_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
 }
 
 static void jazz_led_invalidate_display(void *opaque)
@@ -218,7 +218,7 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
     console_write_ch(chardata++, 0x00200100 | buf[0]);
     console_write_ch(chardata++, 0x00200100 | buf[1]);
 
-    dpy_update(s->ds, 0, 0, 2, 1);
+    dpy_text_update(s->ds, 0, 0, 2, 1);
 }
 
 static int jazz_led_post_load(void *opaque, int version_id)
diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
index 8d36bc1..833881c 100644
--- a/hw/milkymist-vgafb.c
+++ b/hw/milkymist-vgafb.c
@@ -134,7 +134,7 @@ static void vgafb_update_display(void *opaque)
                                &first, &last);
 
     if (first >= 0) {
-        dpy_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
+        dpy_gfx_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
     }
     s->invalidate = 0;
 }
diff --git a/hw/musicpal.c b/hw/musicpal.c
index beec76b..e0c57c8 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -526,7 +526,7 @@ static void lcd_refresh(void *opaque)
                   ds_get_bits_per_pixel(s->ds));
     }
 
-    dpy_update(s->ds, 0, 0, 128*3, 64*3);
+    dpy_gfx_update(s->ds, 0, 0, 128*3, 64*3);
 }
 
 static void lcd_invalidate(void *opaque)
diff --git a/hw/nseries.c b/hw/nseries.c
index 9306aa1..26d5e35 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -1376,7 +1376,7 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
        size until the guest activates the display.  */
     ds = get_displaystate();
     ds->surface = qemu_resize_displaysurface(ds, 800, 480);
-    dpy_resize(ds);
+    dpy_gfx_resize(ds);
 }
 
 static struct arm_boot_info n800_binfo = {
diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
index bf177c2..d7ae303 100644
--- a/hw/omap_lcdc.c
+++ b/hw/omap_lcdc.c
@@ -219,7 +219,7 @@ static void omap_update_display(void *opaque)
                                draw_line, omap_lcd->palette,
                                &first, &last);
     if (first >= 0) {
-        dpy_update(omap_lcd->state, 0, first, width, last - first + 1);
+        dpy_gfx_update(omap_lcd->state, 0, first, width, last - first + 1);
     }
     omap_lcd->invalidate = 0;
 }
diff --git a/hw/palm.c b/hw/palm.c
index d263051..6f6f414 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -273,7 +273,7 @@ static void palmte_init(QEMUMachineInitArgs *args)
        will set the size once configured, so this just sets an initial
        size until the guest activates the display.  */
     ds->surface = qemu_resize_displaysurface(ds, 320, 320);
-    dpy_resize(ds);
+    dpy_gfx_resize(ds);
 }
 
 static QEMUMachine palmte_machine = {
diff --git a/hw/pl110.c b/hw/pl110.c
index 82486b0..79a3f82 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -239,7 +239,7 @@ static void pl110_update_display(void *opaque)
                                fn, s->palette,
                                &first, &last);
     if (first >= 0) {
-        dpy_update(s->ds, 0, first, s->cols, last - first + 1);
+        dpy_gfx_update(s->ds, 0, first, s->cols, last - first + 1);
     }
     s->invalidate = 0;
 }
diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
index 38c3889..b53dfaf 100644
--- a/hw/pxa2xx_lcd.c
+++ b/hw/pxa2xx_lcd.c
@@ -871,20 +871,20 @@ static void pxa2xx_update_display(void *opaque)
     if (miny >= 0) {
         switch (s->orientation) {
         case 0:
-            dpy_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
+            dpy_gfx_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
             break;
         case 90:
-            dpy_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
+            dpy_gfx_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
             break;
         case 180:
             maxy = s->yres - maxy - 1;
             miny = s->yres - miny - 1;
-            dpy_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
+            dpy_gfx_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
             break;
         case 270:
             maxy = s->yres - maxy - 1;
             miny = s->yres - miny - 1;
-            dpy_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
+            dpy_gfx_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
             break;
         }
     }
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index e8cf29e..47eb8b4 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -123,17 +123,17 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
                     qxl->guest_primary.surface.width,
                     qxl->guest_primary.surface.height);
         }
-        dpy_resize(vga->ds);
+        dpy_gfx_resize(vga->ds);
     }
     for (i = 0; i < qxl->num_dirty_rects; i++) {
         if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
             break;
         }
         qxl_blit(qxl, qxl->dirty+i);
-        dpy_update(vga->ds,
-                   qxl->dirty[i].left, qxl->dirty[i].top,
-                   qxl->dirty[i].right - qxl->dirty[i].left,
-                   qxl->dirty[i].bottom - qxl->dirty[i].top);
+        dpy_gfx_update(vga->ds,
+                       qxl->dirty[i].left, qxl->dirty[i].top,
+                       qxl->dirty[i].right - qxl->dirty[i].left,
+                       qxl->dirty[i].bottom - qxl->dirty[i].top);
     }
     qxl->num_dirty_rects = 0;
 }
diff --git a/hw/qxl.c b/hw/qxl.c
index d54daf6..1f56fcd 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1864,8 +1864,8 @@ static void display_refresh(struct DisplayState *ds)
 }
 
 static DisplayChangeListener display_listener = {
-    .dpy_update  = display_update,
-    .dpy_resize  = display_resize,
+    .dpy_gfx_update  = display_update,
+    .dpy_gfx_resize  = display_resize,
     .dpy_refresh = display_refresh,
 };
 
diff --git a/hw/sm501.c b/hw/sm501.c
index 4aafe49..50324cd 100644
--- a/hw/sm501.c
+++ b/hw/sm501.c
@@ -1351,7 +1351,7 @@ static void sm501_draw_crt(SM501State * s)
 	} else {
 	    if (y_start >= 0) {
 		/* flush to display */
-		dpy_update(s->ds, 0, y_start, width, y - y_start);
+                dpy_gfx_update(s->ds, 0, y_start, width, y - y_start);
 		y_start = -1;
 	    }
 	}
@@ -1362,7 +1362,7 @@ static void sm501_draw_crt(SM501State * s)
 
     /* complete flush to display */
     if (y_start >= 0)
-	dpy_update(s->ds, 0, y_start, width, y - y_start);
+        dpy_gfx_update(s->ds, 0, y_start, width, y - y_start);
 
     /* clear dirty flags */
     if (page_min != ~0l) {
diff --git a/hw/ssd0303.c b/hw/ssd0303.c
index 4e1ee6e..d7fd828 100644
--- a/hw/ssd0303.c
+++ b/hw/ssd0303.c
@@ -252,7 +252,7 @@ static void ssd0303_update_display(void *opaque)
         }
     }
     s->redraw = 0;
-    dpy_update(s->ds, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
+    dpy_gfx_update(s->ds, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
 }
 
 static void ssd0303_invalidate_display(void * opaque)
diff --git a/hw/ssd0323.c b/hw/ssd0323.c
index 9c42d64..4098830 100644
--- a/hw/ssd0323.c
+++ b/hw/ssd0323.c
@@ -260,7 +260,7 @@ static void ssd0323_update_display(void *opaque)
         }
     }
     s->redraw = 0;
-    dpy_update(s->ds, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
+    dpy_gfx_update(s->ds, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
 }
 
 static void ssd0323_invalidate_display(void * opaque)
diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
index 31d4f26..f032027 100644
--- a/hw/tc6393xb.c
+++ b/hw/tc6393xb.c
@@ -454,7 +454,7 @@ static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
             return;
     }
 
-    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
+    dpy_gfx_update(s->ds, 0, 0, s->scr_width, s->scr_height);
 }
 
 static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
@@ -472,7 +472,7 @@ static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
         d += ds_get_linesize(s->ds);
     }
 
-    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
+    dpy_gfx_update(s->ds, 0, 0, s->scr_width, s->scr_height);
 }
 
 static void tc6393xb_update_display(void *opaque)
diff --git a/hw/tcx.c b/hw/tcx.c
index 7abe865..7aee2a9 100644
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -268,8 +268,8 @@ static void tcx_update_display(void *opaque)
         } else {
             if (y_start >= 0) {
                 /* flush to display */
-                dpy_update(ts->ds, 0, y_start,
-                           ts->width, y - y_start);
+                dpy_gfx_update(ts->ds, 0, y_start,
+                               ts->width, y - y_start);
                 y_start = -1;
             }
             d += dd * 4;
@@ -278,8 +278,8 @@ static void tcx_update_display(void *opaque)
     }
     if (y_start >= 0) {
         /* flush to display */
-        dpy_update(ts->ds, 0, y_start,
-                   ts->width, y - y_start);
+        dpy_gfx_update(ts->ds, 0, y_start,
+                       ts->width, y - y_start);
     }
     /* reset modified pages */
     if (page_max >= page_min) {
@@ -344,8 +344,8 @@ static void tcx24_update_display(void *opaque)
         } else {
             if (y_start >= 0) {
                 /* flush to display */
-                dpy_update(ts->ds, 0, y_start,
-                           ts->width, y - y_start);
+                dpy_gfx_update(ts->ds, 0, y_start,
+                               ts->width, y - y_start);
                 y_start = -1;
             }
             d += dd * 4;
@@ -356,8 +356,8 @@ static void tcx24_update_display(void *opaque)
     }
     if (y_start >= 0) {
         /* flush to display */
-        dpy_update(ts->ds, 0, y_start,
-                   ts->width, y - y_start);
+        dpy_gfx_update(ts->ds, 0, y_start,
+                       ts->width, y - y_start);
     }
     /* reset modified pages */
     if (page_max >= page_min) {
diff --git a/hw/vga.c b/hw/vga.c
index f3256cb..dc8ddde 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1456,8 +1456,8 @@ static void vga_draw_text(VGACommonState *s, int full_update)
             ch_attr_ptr++;
         }
         if (cx_max != -1) {
-            dpy_update(s->ds, cx_min * cw, cy * cheight,
-                       (cx_max - cx_min + 1) * cw, cheight);
+            dpy_gfx_update(s->ds, cx_min * cw, cy * cheight,
+                           (cx_max - cx_min + 1) * cw, cheight);
         }
         dest += linesize * cheight;
         line1 = line + cheight;
@@ -1688,7 +1688,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
             s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
 #endif
-            dpy_resize(s->ds);
+            dpy_gfx_resize(s->ds);
         } else {
             qemu_console_resize(s->ds, disp_width, height);
         }
@@ -1702,7 +1702,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     } else if (is_buffer_shared(s->ds->surface) &&
                (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
         s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
-        dpy_setdata(s->ds);
+        dpy_gfx_setdata(s->ds);
     }
 
     s->rgb_to_pixel =
@@ -1807,8 +1807,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         } else {
             if (y_start >= 0) {
                 /* flush to display */
-                dpy_update(s->ds, 0, y_start,
-                           disp_width, y - y_start);
+                dpy_gfx_update(s->ds, 0, y_start,
+                               disp_width, y - y_start);
                 y_start = -1;
             }
         }
@@ -1828,8 +1828,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     }
     if (y_start >= 0) {
         /* flush to display */
-        dpy_update(s->ds, 0, y_start,
-                   disp_width, y - y_start);
+        dpy_gfx_update(s->ds, 0, y_start,
+                       disp_width, y - y_start);
     }
     /* reset modified pages */
     if (page_max >= page_min) {
@@ -1863,8 +1863,8 @@ static void vga_draw_blank(VGACommonState *s, int full_update)
         memset(d, val, w);
         d += ds_get_linesize(s->ds);
     }
-    dpy_update(s->ds, 0, 0,
-               s->last_scr_width, s->last_scr_height);
+    dpy_gfx_update(s->ds, 0, 0,
+                   s->last_scr_width, s->last_scr_height);
 }
 
 #define GMODE_TEXT     0
@@ -2052,9 +2052,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             cw != s->last_cw || cheight != s->last_ch) {
             s->last_scr_width = width * cw;
             s->last_scr_height = height * cheight;
-            s->ds->surface->width = width;
-            s->ds->surface->height = height;
-            dpy_resize(s->ds);
+            dpy_text_resize(s->ds, width, height);
             s->last_width = width;
             s->last_height = height;
             s->last_ch = cheight;
@@ -2087,7 +2085,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             for (i = 0; i < size; src ++, dst ++, i ++)
                 console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
 
-            dpy_update(s->ds, 0, 0, width, height);
+            dpy_text_update(s->ds, 0, 0, width, height);
         } else {
             c_max = 0;
 
@@ -2110,7 +2108,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
 
             if (c_min <= c_max) {
                 i = TEXTMODE_Y(c_min);
-                dpy_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
+                dpy_text_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
             }
         }
 
@@ -2136,9 +2134,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
     s->last_width = 60;
     s->last_height = height = 3;
     dpy_text_cursor(s->ds, -1, -1);
-    s->ds->surface->width = s->last_width;
-    s->ds->surface->height = height;
-    dpy_resize(s->ds);
+    dpy_text_resize(s->ds, s->last_width, height);
 
     for (dst = chardata, i = 0; i < s->last_width * height; i ++)
         console_write_ch(dst ++, ' ');
@@ -2149,7 +2145,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
     for (i = 0; i < size; i ++)
         console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
 
-    dpy_update(s->ds, 0, 0, s->last_width, height);
+    dpy_text_update(s->ds, 0, 0, s->last_width, height);
 }
 
 static uint64_t vga_mem_read(void *opaque, hwaddr addr,
diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
index dc92790..34532e5 100644
--- a/hw/vmware_vga.c
+++ b/hw/vmware_vga.c
@@ -321,14 +321,14 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
     for (; line > 0; line --, src += bypl, dst += bypl)
         memcpy(dst, src, width);
 
-    dpy_update(s->vga.ds, x, y, w, h);
+    dpy_gfx_update(s->vga.ds, x, y, w, h);
 }
 
 static inline void vmsvga_update_screen(struct vmsvga_state_s *s)
 {
     memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr,
            s->bypp * s->width * s->height);
-    dpy_update(s->vga.ds, 0, 0, s->width, s->height);
+    dpy_gfx_update(s->vga.ds, 0, 0, s->width, s->height);
 }
 
 static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
diff --git a/ui/curses.c b/ui/curses.c
index c2be2c6..b40b223 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -95,17 +95,16 @@ static void curses_calc_pad(void)
     }
 }
 
-static void curses_resize(DisplayState *ds)
+static void curses_resize(DisplayState *ds, int width, int height)
 {
-    if (ds_get_width(ds) == gwidth && ds_get_height(ds) == gheight)
+    if (width == gwidth && height == gheight) {
         return;
+    }
 
-    gwidth = ds_get_width(ds);
-    gheight = ds_get_height(ds);
+    gwidth = width;
+    gheight = height;
 
     curses_calc_pad();
-    ds->surface->width = width * FONT_WIDTH;
-    ds->surface->height = height * FONT_HEIGHT;
 }
 
 #ifndef _WIN32
@@ -167,8 +166,6 @@ static void curses_refresh(DisplayState *ds)
         clear();
         refresh();
         curses_calc_pad();
-        ds->surface->width = FONT_WIDTH * width;
-        ds->surface->height = FONT_HEIGHT * height;
         vga_hw_invalidate();
         invalidate = 0;
     }
@@ -195,8 +192,6 @@ static void curses_refresh(DisplayState *ds)
             refresh();
             curses_calc_pad();
             curses_update(ds, 0, 0, width, height);
-            ds->surface->width = FONT_WIDTH * width;
-            ds->surface->height = FONT_HEIGHT * height;
             continue;
         }
 #endif
@@ -355,13 +350,11 @@ void curses_display_init(DisplayState *ds, int full_screen)
 #endif
 
     dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
-    dcl->dpy_update = curses_update;
-    dcl->dpy_resize = curses_resize;
+    dcl->dpy_text_update = curses_update;
+    dcl->dpy_text_resize = curses_resize;
     dcl->dpy_refresh = curses_refresh;
     dcl->dpy_text_cursor = curses_cursor_position;
     register_displaychangelistener(ds, dcl);
-    qemu_free_displaysurface(ds);
-    ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen);
 
     invalidate = 1;
 }
diff --git a/ui/sdl.c b/ui/sdl.c
index f8ead93..fac1a47 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -553,7 +553,7 @@ static void sdl_scale(DisplayState *ds, int width, int height)
     if (!is_buffer_shared(ds->surface)) {
         ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds),
                                                  ds_get_height(ds));
-        dpy_resize(ds);
+        dpy_gfx_resize(ds);
     }
 }
 
@@ -1020,11 +1020,11 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     }
 
     dcl = g_malloc0(sizeof(DisplayChangeListener));
-    dcl->dpy_update = sdl_update;
-    dcl->dpy_resize = sdl_resize;
+    dcl->dpy_gfx_update = sdl_update;
+    dcl->dpy_gfx_resize = sdl_resize;
     dcl->dpy_refresh = sdl_refresh;
-    dcl->dpy_setdata = sdl_setdata;
-    dcl->dpy_fill = sdl_fill;
+    dcl->dpy_gfx_setdata = sdl_setdata;
+    dcl->dpy_gfx_fill = sdl_fill;
     dcl->dpy_mouse_set = sdl_mouse_warp;
     dcl->dpy_cursor_define = sdl_mouse_define;
     register_displaychangelistener(ds, dcl);
@@ -1034,7 +1034,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     da->resize_displaysurface = sdl_resize_displaysurface;
     da->free_displaysurface = sdl_free_displaysurface;
     if (register_displayallocator(ds, da) == da) {
-        dpy_resize(ds);
+        dpy_gfx_resize(ds);
     }
 
     mouse_mode_notifier.notify = sdl_mouse_mode_change;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 5779fa8..fb99148 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -571,8 +571,8 @@ static void display_refresh(struct DisplayState *ds)
 }
 
 static DisplayChangeListener display_listener = {
-    .dpy_update  = display_update,
-    .dpy_resize  = display_resize,
+    .dpy_gfx_update  = display_update,
+    .dpy_gfx_resize  = display_resize,
     .dpy_refresh = display_refresh,
 };
 
diff --git a/ui/vnc.c b/ui/vnc.c
index 1b70db7..0ae1c74 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2753,10 +2753,10 @@ void vnc_display_init(DisplayState *ds)
     qemu_mutex_init(&vs->mutex);
     vnc_start_worker_thread();
 
-    dcl->dpy_copy = vnc_dpy_copy;
-    dcl->dpy_update = vnc_dpy_update;
-    dcl->dpy_resize = vnc_dpy_resize;
-    dcl->dpy_setdata = vnc_dpy_setdata;
+    dcl->dpy_gfx_copy = vnc_dpy_copy;
+    dcl->dpy_gfx_update = vnc_dpy_update;
+    dcl->dpy_gfx_resize = vnc_dpy_resize;
+    dcl->dpy_gfx_setdata = vnc_dpy_setdata;
     dcl->dpy_mouse_set = vnc_mouse_set;
     dcl->dpy_cursor_define = vnc_dpy_cursor_define;
     register_displaychangelistener(ds, dcl);
diff --git a/vl.c b/vl.c
index 4c45b02..8716fc0 100644
--- a/vl.c
+++ b/vl.c
@@ -1375,11 +1375,18 @@ 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->dpy_refresh != NULL) {
             need_timer = true;
-            break;
+        }
+        if (dcl->dpy_gfx_update != NULL) {
+            have_gfx = true;
+        }
+        if (dcl->dpy_text_update != NULL) {
+            have_text = true;
         }
     }
 
@@ -1392,6 +1399,9 @@ void gui_setup_refresh(DisplayState *ds)
         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 {
@@ -3866,7 +3876,7 @@ int main(int argc, char **argv, char **envp)
 #endif
 
     /* display setup */
-    dpy_resize(ds);
+    dpy_gfx_resize(ds);
     text_consoles_set_display(ds);
 
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 06/22] console: init displaychangelisteners on register
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 05/22] console: untangle gfx & txt updates Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 07/22] vga: fix text mode updating Gerd Hoffmann
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.h |    3 +++
 vl.c      |    1 -
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/console.h b/console.h
index 00e2f03..7e0ac76 100644
--- a/console.h
+++ b/console.h
@@ -241,6 +241,9 @@ static inline void register_displaychangelistener(DisplayState *ds, DisplayChang
 {
     QLIST_INSERT_HEAD(&ds->listeners, dcl, next);
     gui_setup_refresh(ds);
+    if (dcl->dpy_gfx_resize) {
+        dcl->dpy_gfx_resize(ds);
+    }
 }
 
 static inline void unregister_displaychangelistener(DisplayState *ds,
diff --git a/vl.c b/vl.c
index 8716fc0..df776e9 100644
--- a/vl.c
+++ b/vl.c
@@ -3876,7 +3876,6 @@ int main(int argc, char **argv, char **envp)
 #endif
 
     /* display setup */
-    dpy_gfx_resize(ds);
     text_consoles_set_display(ds);
 
     if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 07/22] vga: fix text mode updating
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 06/22] console: init displaychangelisteners on register Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 08/22] console: remove dpy_gfx_fill Gerd Hoffmann
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

With both text (curses) and graphics (vnc/sdl/spice/...) display active
vga text mode emulation fails to update both correctly.  Depending on
whenever vga_update_text() or vga_draw_text() happens to be called first
only the text display or only the graphics display will see display
resolution changes and full redraws.

Fix it by calling both text/gfx resize functions in both code paths and
keep track of full screen redraws needed in VGACommonState fields.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/vga.c     |   19 +++++++++++++++++++
 hw/vga_int.h |    2 ++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/vga.c b/hw/vga.c
index dc8ddde..f31dbdd 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1346,6 +1346,7 @@ static void vga_draw_text(VGACommonState *s, int full_update)
         s->last_scr_width = width * cw;
         s->last_scr_height = height * cheight;
         qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
+        dpy_text_resize(s->ds, width, height);
         s->last_depth = 0;
         s->last_width = width;
         s->last_height = height;
@@ -1359,6 +1360,14 @@ static void vga_draw_text(VGACommonState *s, int full_update)
     palette = s->last_palette;
     x_incr = cw * ((ds_get_bits_per_pixel(s->ds) + 7) >> 3);
 
+    if (full_update) {
+        s->full_update_text = 1;
+    }
+    if (s->full_update_gfx) {
+        s->full_update_gfx = 0;
+        full_update |= 1;
+    }
+
     cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
                      s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
     if (cursor_offset != s->cursor_offset ||
@@ -2052,7 +2061,9 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             cw != s->last_cw || cheight != s->last_ch) {
             s->last_scr_width = width * cw;
             s->last_scr_height = height * cheight;
+            qemu_console_resize(s->ds, s->last_scr_width, s->last_scr_height);
             dpy_text_resize(s->ds, width, height);
+            s->last_depth = 0;
             s->last_width = width;
             s->last_height = height;
             s->last_ch = cheight;
@@ -2060,6 +2071,14 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
             full_update = 1;
         }
 
+        if (full_update) {
+            s->full_update_gfx = 1;
+        }
+        if (s->full_update_text) {
+            s->full_update_text = 0;
+            full_update |= 1;
+        }
+
         /* Update "hardware" cursor */
         cursor_offset = ((s->cr[VGA_CRTC_CURSOR_HI] << 8) |
                          s->cr[VGA_CRTC_CURSOR_LO]) - s->start_addr;
diff --git a/hw/vga_int.h b/hw/vga_int.h
index 22f1706..d4da777 100644
--- a/hw/vga_int.h
+++ b/hw/vga_int.h
@@ -154,6 +154,8 @@ typedef struct VGACommonState {
     vga_hw_invalidate_ptr invalidate;
     vga_hw_screen_dump_ptr screen_dump;
     vga_hw_text_update_ptr text_update;
+    bool full_update_text;
+    bool full_update_gfx;
     /* hardware mouse cursor support */
     uint32_t invalidated_y_table[VGA_MAX_HEIGHT / 32];
     void (*cursor_invalidate)(struct VGACommonState *s);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 08/22] console: remove dpy_gfx_fill
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 07/22] vga: fix text mode updating Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 09/22] console: remove DisplayAllocator Gerd Hoffmann
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Unused code.  'nuff said.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.h |   13 -------------
 ui/sdl.c  |    7 -------
 2 files changed, 0 insertions(+), 20 deletions(-)

diff --git a/console.h b/console.h
index 7e0ac76..6492e67 100644
--- a/console.h
+++ b/console.h
@@ -161,8 +161,6 @@ struct DisplayChangeListener {
     void (*dpy_gfx_setdata)(struct DisplayState *s);
     void (*dpy_gfx_copy)(struct DisplayState *s, int src_x, int src_y,
                          int dst_x, int dst_y, int w, int h);
-    void (*dpy_gfx_fill)(struct DisplayState *s, int x, int y,
-                         int w, int h, uint32_t c);
 
     void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
     void (*dpy_text_resize)(struct DisplayState *s, int w, int h);
@@ -306,17 +304,6 @@ static inline void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
     }
 }
 
-static inline void dpy_gfx_fill(struct DisplayState *s, int x, int y,
-                                int w, int h, uint32_t c)
-{
-    struct DisplayChangeListener *dcl;
-    QLIST_FOREACH(dcl, &s->listeners, next) {
-        if (dcl->dpy_gfx_fill) {
-            dcl->dpy_gfx_fill(s, x, y, w, h, c);
-        }
-    }
-}
-
 static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
 {
     struct DisplayChangeListener *dcl;
diff --git a/ui/sdl.c b/ui/sdl.c
index fac1a47..c3ba79f 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -899,12 +899,6 @@ static void sdl_refresh(DisplayState *ds)
     }
 }
 
-static void sdl_fill(DisplayState *ds, int x, int y, int w, int h, uint32_t c)
-{
-    SDL_Rect dst = { x, y, w, h };
-    SDL_FillRect(real_screen, &dst, c);
-}
-
 static void sdl_mouse_warp(DisplayState *ds, int x, int y, int on)
 {
     if (on) {
@@ -1024,7 +1018,6 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     dcl->dpy_gfx_resize = sdl_resize;
     dcl->dpy_refresh = sdl_refresh;
     dcl->dpy_gfx_setdata = sdl_setdata;
-    dcl->dpy_gfx_fill = sdl_fill;
     dcl->dpy_mouse_set = sdl_mouse_warp;
     dcl->dpy_cursor_define = sdl_mouse_define;
     register_displaychangelistener(ds, dcl);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 09/22] console: remove DisplayAllocator
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 08/22] console: remove dpy_gfx_fill Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 10/22] pixman: add submodule Gerd Hoffmann
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Causes [temporary] preformance regression with 24bpp vga modes @ sdl.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c     |   52 +++++++++----------------
 console.h     |   34 +++--------------
 qemu-common.h |    1 -
 ui/sdl.c      |  117 +++------------------------------------------------------
 4 files changed, 31 insertions(+), 173 deletions(-)

diff --git a/console.c b/console.c
index 61812c7..71cc543 100644
--- a/console.c
+++ b/console.c
@@ -1294,9 +1294,10 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
     return s;
 }
 
-static DisplaySurface* defaultallocator_create_displaysurface(int width, int height)
+DisplaySurface *qemu_create_displaysurface(DisplayState *ds,
+                                           int width, int height)
 {
-    DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
+    DisplaySurface *surface = g_new0(DisplaySurface, 1);
 
     int linesize = width * 4;
     qemu_alloc_display(surface, width, height, linesize,
@@ -1304,13 +1305,15 @@ static DisplaySurface* defaultallocator_create_displaysurface(int width, int hei
     return surface;
 }
 
-static DisplaySurface* defaultallocator_resize_displaysurface(DisplaySurface *surface,
-                                          int width, int height)
+DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
+                                           int width, int height)
 {
     int linesize = width * 4;
-    qemu_alloc_display(surface, width, height, linesize,
+
+    trace_displaysurface_resize(ds, ds->surface, width, height);
+    qemu_alloc_display(ds->surface, width, height, linesize,
                        qemu_default_pixelformat(32), 0);
-    return surface;
+    return ds->surface;
 }
 
 void qemu_alloc_display(DisplaySurface *surface, int width, int height,
@@ -1323,7 +1326,7 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
     surface->pf = pf;
     if (surface->flags & QEMU_ALLOCATED_FLAG) {
         data = g_realloc(surface->data,
-                            surface->linesize * surface->height);
+                         surface->linesize * surface->height);
     } else {
         data = g_malloc(surface->linesize * surface->height);
     }
@@ -1334,7 +1337,7 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
 #endif
 }
 
-DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
+DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
                                               int linesize, uint8_t *data)
 {
     DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
@@ -1351,28 +1354,24 @@ DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
     return surface;
 }
 
-static void defaultallocator_free_displaysurface(DisplaySurface *surface)
+void qemu_free_displaysurface(DisplayState *ds)
 {
-    if (surface == NULL)
+    trace_displaysurface_free(ds, ds->surface);
+    if (ds->surface == NULL) {
         return;
-    if (surface->flags & QEMU_ALLOCATED_FLAG)
-        g_free(surface->data);
-    g_free(surface);
+    }
+    if (ds->surface->flags & QEMU_ALLOCATED_FLAG) {
+        g_free(ds->surface->data);
+    }
+    g_free(ds->surface);
 }
 
-static struct DisplayAllocator default_allocator = {
-    defaultallocator_create_displaysurface,
-    defaultallocator_resize_displaysurface,
-    defaultallocator_free_displaysurface
-};
-
 static void dumb_display_init(void)
 {
     DisplayState *ds = g_malloc0(sizeof(DisplayState));
     int width = 640;
     int height = 480;
 
-    ds->allocator = &default_allocator;
     if (is_fixedsize_console()) {
         width = active_console->g_width;
         height = active_console->g_height;
@@ -1402,18 +1401,6 @@ DisplayState *get_displaystate(void)
     return display_state;
 }
 
-DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
-{
-    if(ds->allocator ==  &default_allocator) {
-        DisplaySurface *surf;
-        surf = da->create_displaysurface(ds_get_width(ds), ds_get_height(ds));
-        defaultallocator_free_displaysurface(ds->surface);
-        ds->surface = surf;
-        ds->allocator = da;
-    }
-    return ds->allocator;
-}
-
 DisplayState *graphic_console_init(vga_hw_update_ptr update,
                                    vga_hw_invalidate_ptr invalidate,
                                    vga_hw_screen_dump_ptr screen_dump,
@@ -1424,7 +1411,6 @@ DisplayState *graphic_console_init(vga_hw_update_ptr update,
     DisplayState *ds;
 
     ds = (DisplayState *) g_malloc0(sizeof(DisplayState));
-    ds->allocator = &default_allocator; 
     ds->surface = qemu_create_displaysurface(ds, 640, 480);
 
     s = new_console(ds, GRAPHIC_CONSOLE);
diff --git a/console.h b/console.h
index 6492e67..6be880a 100644
--- a/console.h
+++ b/console.h
@@ -107,7 +107,6 @@ void kbd_put_keysym(int keysym);
 
 #define QEMU_BIG_ENDIAN_FLAG    0x01
 #define QEMU_ALLOCATED_FLAG     0x02
-#define QEMU_REALPIXELS_FLAG    0x04
 
 struct PixelFormat {
     uint8_t bits_per_pixel;
@@ -172,12 +171,6 @@ struct DisplayChangeListener {
     QLIST_ENTRY(DisplayChangeListener) next;
 };
 
-struct DisplayAllocator {
-    DisplaySurface* (*create_displaysurface)(int width, int height);
-    DisplaySurface* (*resize_displaysurface)(DisplaySurface *surface, int width, int height);
-    void (*free_displaysurface)(DisplaySurface *surface);
-};
-
 struct DisplayState {
     struct DisplaySurface *surface;
     void *opaque;
@@ -185,7 +178,6 @@ struct DisplayState {
     bool have_gfx;
     bool have_text;
 
-    struct DisplayAllocator* allocator;
     QLIST_HEAD(, DisplayChangeListener) listeners;
 
     struct DisplayState *next;
@@ -200,24 +192,11 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
 PixelFormat qemu_different_endianness_pixelformat(int bpp);
 PixelFormat qemu_default_pixelformat(int bpp);
 
-DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da);
-
-static inline DisplaySurface* qemu_create_displaysurface(DisplayState *ds, int width, int height)
-{
-    return ds->allocator->create_displaysurface(width, height);    
-}
-
-static inline DisplaySurface* qemu_resize_displaysurface(DisplayState *ds, int width, int height)
-{
-    trace_displaysurface_resize(ds, ds->surface, width, height);
-    return ds->allocator->resize_displaysurface(ds->surface, width, height);
-}
-
-static inline void qemu_free_displaysurface(DisplayState *ds)
-{
-    trace_displaysurface_free(ds, ds->surface);
-    ds->allocator->free_displaysurface(ds->surface);
-}
+DisplaySurface *qemu_create_displaysurface(DisplayState *ds,
+                                           int width, int height);
+DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
+                                           int width, int height);
+void qemu_free_displaysurface(DisplayState *ds);
 
 static inline int is_surface_bgr(DisplaySurface *surface)
 {
@@ -229,8 +208,7 @@ static inline int is_surface_bgr(DisplaySurface *surface)
 
 static inline int is_buffer_shared(DisplaySurface *surface)
 {
-    return (!(surface->flags & QEMU_ALLOCATED_FLAG) &&
-            !(surface->flags & QEMU_REALPIXELS_FLAG));
+    return !(surface->flags & QEMU_ALLOCATED_FLAG);
 }
 
 void gui_setup_refresh(DisplayState *ds);
diff --git a/qemu-common.h b/qemu-common.h
index fdd0dbc..89cec1d 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -262,7 +262,6 @@ typedef struct DriveInfo DriveInfo;
 typedef struct DisplayState DisplayState;
 typedef struct DisplayChangeListener DisplayChangeListener;
 typedef struct DisplaySurface DisplaySurface;
-typedef struct DisplayAllocator DisplayAllocator;
 typedef struct PixelFormat PixelFormat;
 typedef struct QemuConsole QemuConsole;
 typedef struct CharDriverState CharDriverState;
diff --git a/ui/sdl.c b/ui/sdl.c
index c3ba79f..37f01b2 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -55,7 +55,6 @@ static int absolute_enabled = 0;
 static int guest_cursor = 0;
 static int guest_x, guest_y;
 static SDL_Cursor *guest_sprite = NULL;
-static uint8_t allocator;
 static SDL_PixelFormat host_format;
 static int scaling_active = 0;
 static Notifier mouse_mode_notifier;
@@ -117,108 +116,13 @@ static void do_sdl_resize(int width, int height, int bpp)
 
 static void sdl_resize(DisplayState *ds)
 {
-    if  (!allocator) {
-        if (!scaling_active)
-            do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
-        else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds))
-            do_sdl_resize(real_screen->w, real_screen->h, ds_get_bits_per_pixel(ds));
-        sdl_setdata(ds);
-    } else {
-        if (guest_screen != NULL) {
-            SDL_FreeSurface(guest_screen);
-            guest_screen = NULL;
-        }
-    }
-}
-
-static PixelFormat sdl_to_qemu_pixelformat(SDL_PixelFormat *sdl_pf)
-{
-    PixelFormat qemu_pf;
-
-    memset(&qemu_pf, 0x00, sizeof(PixelFormat));
-
-    qemu_pf.bits_per_pixel = sdl_pf->BitsPerPixel;
-    qemu_pf.bytes_per_pixel = sdl_pf->BytesPerPixel;
-    qemu_pf.depth = (qemu_pf.bits_per_pixel) == 32 ? 24 : (qemu_pf.bits_per_pixel);
-
-    qemu_pf.rmask = sdl_pf->Rmask;
-    qemu_pf.gmask = sdl_pf->Gmask;
-    qemu_pf.bmask = sdl_pf->Bmask;
-    qemu_pf.amask = sdl_pf->Amask;
-
-    qemu_pf.rshift = sdl_pf->Rshift;
-    qemu_pf.gshift = sdl_pf->Gshift;
-    qemu_pf.bshift = sdl_pf->Bshift;
-    qemu_pf.ashift = sdl_pf->Ashift;
-
-    qemu_pf.rbits = 8 - sdl_pf->Rloss;
-    qemu_pf.gbits = 8 - sdl_pf->Gloss;
-    qemu_pf.bbits = 8 - sdl_pf->Bloss;
-    qemu_pf.abits = 8 - sdl_pf->Aloss;
-
-    qemu_pf.rmax = ((1 << qemu_pf.rbits) - 1);
-    qemu_pf.gmax = ((1 << qemu_pf.gbits) - 1);
-    qemu_pf.bmax = ((1 << qemu_pf.bbits) - 1);
-    qemu_pf.amax = ((1 << qemu_pf.abits) - 1);
-
-    return qemu_pf;
-}
-
-static DisplaySurface* sdl_create_displaysurface(int width, int height)
-{
-    DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
-
-    surface->width = width;
-    surface->height = height;
-
-    if (scaling_active) {
-        int linesize;
-        PixelFormat pf;
-        if (host_format.BytesPerPixel != 2 && host_format.BytesPerPixel != 4) {
-            linesize = width * 4;
-            pf = qemu_default_pixelformat(32);
-        } else {
-            linesize = width * host_format.BytesPerPixel;
-            pf = sdl_to_qemu_pixelformat(&host_format);
-        }
-        qemu_alloc_display(surface, width, height, linesize, pf, 0);
-        return surface;
+    if (!scaling_active) {
+        do_sdl_resize(ds_get_width(ds), ds_get_height(ds), 0);
+    } else if (real_screen->format->BitsPerPixel != ds_get_bits_per_pixel(ds)) {
+        do_sdl_resize(real_screen->w, real_screen->h,
+                      ds_get_bits_per_pixel(ds));
     }
-
-    if (host_format.BitsPerPixel == 16)
-        do_sdl_resize(width, height, 16);
-    else
-        do_sdl_resize(width, height, 32);
-
-    surface->pf = sdl_to_qemu_pixelformat(real_screen->format);
-    surface->linesize = real_screen->pitch;
-    surface->data = real_screen->pixels;
-
-#ifdef HOST_WORDS_BIGENDIAN
-    surface->flags = QEMU_REALPIXELS_FLAG | QEMU_BIG_ENDIAN_FLAG;
-#else
-    surface->flags = QEMU_REALPIXELS_FLAG;
-#endif
-    allocator = 1;
-
-    return surface;
-}
-
-static void sdl_free_displaysurface(DisplaySurface *surface)
-{
-    allocator = 0;
-    if (surface == NULL)
-        return;
-
-    if (surface->flags & QEMU_ALLOCATED_FLAG)
-        g_free(surface->data);
-    g_free(surface);
-}
-
-static DisplaySurface* sdl_resize_displaysurface(DisplaySurface *surface, int width, int height)
-{
-    sdl_free_displaysurface(surface);
-    return sdl_create_displaysurface(width, height);
+    sdl_setdata(ds);
 }
 
 /* generic keyboard conversion */
@@ -949,7 +853,6 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
 {
     int flags;
     uint8_t data = 0;
-    DisplayAllocator *da;
     const SDL_VideoInfo *vi;
     char *filename;
 
@@ -1022,14 +925,6 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
     dcl->dpy_cursor_define = sdl_mouse_define;
     register_displaychangelistener(ds, dcl);
 
-    da = g_malloc0(sizeof(DisplayAllocator));
-    da->create_displaysurface = sdl_create_displaysurface;
-    da->resize_displaysurface = sdl_resize_displaysurface;
-    da->free_displaysurface = sdl_free_displaysurface;
-    if (register_displayallocator(ds, da) == da) {
-        dpy_gfx_resize(ds);
-    }
-
     mouse_mode_notifier.notify = sdl_mouse_mode_change;
     qemu_add_mouse_mode_change_notifier(&mouse_mode_notifier);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 10/22] pixman: add submodule
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 09/22] console: remove DisplayAllocator Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 11/22] pixman: windup in configure & makefiles Gerd Hoffmann
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add pixman submodule as fallback for old distros.
Picking version 0.18.4.  This is shipped by rhel6
and also the minimum version needed by spice so this
should serve well as baseline.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 .gitmodules |    3 +++
 pixman      |    1 +
 2 files changed, 4 insertions(+), 0 deletions(-)
 create mode 160000 pixman

diff --git a/.gitmodules b/.gitmodules
index eca876f..cfa2af9 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -19,3 +19,6 @@
 [submodule "roms/sgabios"]
 	path = roms/sgabios
 	url = git://git.qemu.org/sgabios.git
+[submodule "pixman"]
+	path = pixman
+	url = git://anongit.freedesktop.org/pixman
diff --git a/pixman b/pixman
new file mode 160000
index 0000000..97336fa
--- /dev/null
+++ b/pixman
@@ -0,0 +1 @@
+Subproject commit 97336fad32acf802003855cd8bd6477fa49a12e3
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 11/22] pixman: windup in configure & makefiles
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 10/22] pixman: add submodule Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 12/22] pixman: helper functions Gerd Hoffmann
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile  |    9 +++++++++
 configure |   38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile
index b522b10..e4866d9 100644
--- a/Makefile
+++ b/Makefile
@@ -118,6 +118,15 @@ endif
 
 subdir-libcacard: $(oslib-obj-y) $(trace-obj-y) qemu-timer-common.o
 
+subdir-pixman: pixman/Makefile
+	$(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman V="$(V)" all,)
+
+pixman/Makefile: $(SRC_PATH)/pixman/configure
+	(cd pixman; $(SRC_PATH)/pixman/configure --disable-shared --enable-static)
+
+$(SRC_PATH)/pixman/configure:
+	(cd $(SRC_PATH)/pixman; autoreconf -v --install)
+
 $(filter %-softmmu,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) $(common-obj-y) $(extra-obj-y) subdir-libdis
 
 $(filter %-user,$(SUBDIR_RULES)): $(universal-obj-y) $(trace-obj-y) subdir-libdis-user subdir-libuser
diff --git a/configure b/configure
index 9c6ac87..79701ea 100755
--- a/configure
+++ b/configure
@@ -147,6 +147,7 @@ curses=""
 docs=""
 fdt=""
 nptl=""
+pixman=""
 sdl=""
 virtfs=""
 vnc="yes"
@@ -642,6 +643,10 @@ for opt do
     # configure to be used by RPM and similar macros that set
     # lots of directory switches by default.
   ;;
+  --with-system-pixman) pixman="system"
+  ;;
+  --without-system-pixman) pixman="internal"
+  ;;
   --disable-sdl) sdl="no"
   ;;
   --enable-sdl) sdl="yes"
@@ -2095,6 +2100,34 @@ else
 fi
 
 ##########################################
+# pixman support probe
+
+if test "$pixman" = ""; then
+  if $pkg_config pixman-1 > /dev/null 2>&1; then
+    pixman="system"
+  else
+    pixman="internal"
+  fi
+fi
+if test "$pixman" = "system"; then
+  pixman_cflags=`$pkg_config --cflags pixman-1 2>/dev/null`
+  pixman_libs=`$pkg_config --libs pixman-1 2>/dev/null`
+else
+  if test ! -d ${source_path}/pixman/pixman; then
+    echo "ERROR: pixman not present. Your options:"
+    echo "  (1) Prefered: Install the pixman devel package (any recent"
+    echo "      distro should have packages as Xorg needs pixman too)."
+    echo "  (2) Fetch the pixman submodule, using:"
+    echo "      git submodule update --init pixman"
+    exit 1
+  fi
+  pixman_cflags="-I${source_path}/pixman/pixman"
+  pixman_libs="-Lpixman/pixman/.libs -lpixman-1"
+fi
+QEMU_CFLAGS="$QEMU_CFLAGS $pixman_cflags"
+libs_softmmu="$libs_softmmu $pixman_libs"
+
+##########################################
 # libcap probe
 
 if test "$cap" != "no" ; then
@@ -3142,6 +3175,7 @@ echo "-Werror enabled   $werror"
 if test "$darwin" = "yes" ; then
     echo "Cocoa support     $cocoa"
 fi
+echo "pixman            $pixman"
 echo "SDL support       $sdl"
 echo "curses support    $curses"
 echo "curl support      $curl"
@@ -3908,6 +3942,9 @@ if test "$target_softmmu" = "yes" ; then
   if test "$smartcard_nss" = "yes" ; then
     echo "subdir-$target: subdir-libcacard" >> $config_host_mak
   fi
+  if test "$pixman" = "internal" ; then
+    echo "subdir-$target: subdir-pixman" >> $config_host_mak
+  fi
   case "$target_arch2" in
     i386|x86_64)
       echo "CONFIG_HAVE_CORE_DUMP=y" >> $config_target_mak
@@ -4111,6 +4148,7 @@ DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas"
 DIRS="$DIRS roms/seabios roms/vgabios"
 DIRS="$DIRS qapi-generated"
 DIRS="$DIRS libcacard libcacard/libcacard libcacard/trace"
+DIRS="$DIRS pixman"
 FILES="Makefile tests/tcg/Makefile qdict-test-data.txt"
 FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit"
 FILES="$FILES tests/tcg/lm32/Makefile libcacard/Makefile"
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 12/22] pixman: helper functions
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 11/22] pixman: windup in configure & makefiles Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 13/22] pixman: add pixman image to DisplaySurface Gerd Hoffmann
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add some helper functions which will be put
into use by following patches.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.objs |    1 +
 qemu-pixman.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-pixman.h |   32 ++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+), 0 deletions(-)
 create mode 100644 qemu-pixman.c
 create mode 100644 qemu-pixman.h

diff --git a/Makefile.objs b/Makefile.objs
index 9eca179..acca285 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -65,6 +65,7 @@ common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/
 common-obj-y += net.o net/
 common-obj-y += qom/
 common-obj-y += readline.o console.o cursor.o
+common-obj-y += qemu-pixman.o
 common-obj-y += $(oslib-obj-y)
 common-obj-$(CONFIG_WIN32) += os-win32.o
 common-obj-$(CONFIG_POSIX) += os-posix.o
diff --git a/qemu-pixman.c b/qemu-pixman.c
new file mode 100644
index 0000000..7547ed7
--- /dev/null
+++ b/qemu-pixman.c
@@ -0,0 +1,60 @@
+#include "qemu-pixman.h"
+
+int qemu_pixman_get_type(int rshift, int gshift, int bshift)
+{
+    int type = PIXMAN_TYPE_OTHER;
+
+    if (rshift > gshift && gshift > bshift) {
+        if (bshift == 0) {
+            type = PIXMAN_TYPE_ARGB;
+        } else {
+#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 21, 8)
+            type = PIXMAN_TYPE_RGBA;
+#endif
+        }
+    } else if (rshift < gshift && gshift < bshift) {
+        if (rshift == 0) {
+            type = PIXMAN_TYPE_ABGR;
+        } else {
+            type = PIXMAN_TYPE_BGRA;
+        }
+    }
+    return type;
+}
+
+pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf)
+{
+    pixman_format_code_t format;
+    int type;
+
+    type = qemu_pixman_get_type(pf->rshift, pf->gshift, pf->bshift);
+    format = PIXMAN_FORMAT(pf->bits_per_pixel, type,
+                           pf->abits, pf->rbits, pf->gbits, pf->bbits);
+    if (!pixman_format_supported_source(format)) {
+        return 0;
+    }
+    return format;
+}
+
+pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
+                                           int width)
+{
+    pixman_image_t *image = pixman_image_create_bits(format, width, 1, NULL, 0);
+    assert(image != NULL);
+    return image;
+}
+
+void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
+                              int width, int y)
+{
+    pixman_image_composite(PIXMAN_OP_SRC, fb, NULL, linebuf,
+                           0, y, 0, 0, 0, 0, width, 1);
+}
+
+void qemu_pixman_image_unref(pixman_image_t *image)
+{
+    if (image == NULL) {
+        return;
+    }
+    pixman_image_unref(image);
+}
diff --git a/qemu-pixman.h b/qemu-pixman.h
new file mode 100644
index 0000000..7652c41
--- /dev/null
+++ b/qemu-pixman.h
@@ -0,0 +1,32 @@
+#ifndef QEMU_PIXMAN_H
+#define QEMU_PIXMAN_H
+
+#include <pixman.h>
+
+#include "console.h"
+
+/*
+ * pixman image formats are defined to be native endian,
+ * that means host byte order on qemu.  So we go define
+ * fixed formats here for cases where it is needed, like
+ * feeding libjpeg / libpng and writing screenshots.
+ */
+
+#ifdef HOST_WORDS_BIGENDIAN
+# define PIXMAN_BE_r8g8b8     PIXMAN_r8g8b8
+#else
+# define PIXMAN_BE_r8g8b8     PIXMAN_b8g8r8
+#endif
+
+/* -------------------------------------------------------------------- */
+
+int qemu_pixman_get_type(int rshift, int gshift, int bshift);
+pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
+
+pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
+                                           int width);
+void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
+                              int width, int y);
+void qemu_pixman_image_unref(pixman_image_t *image);
+
+#endif /* QEMU_PIXMAN_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 13/22] pixman: add pixman image to DisplaySurface
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 12/22] pixman: helper functions Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 14/22] console: make qemu_alloc_display static Gerd Hoffmann
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Surfaces are now allocated using pixman.  DisplaySurface gets new
struct fields with pixman image and data.  DisplayChangeListeners
can easily start using pixman now.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c |   37 ++++++++++++++++++++++++-------------
 console.h |    3 +++
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/console.c b/console.c
index 71cc543..5e1c5f5 100644
--- a/console.c
+++ b/console.c
@@ -1319,18 +1319,23 @@ DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
 void qemu_alloc_display(DisplaySurface *surface, int width, int height,
                         int linesize, PixelFormat pf, int newflags)
 {
-    void *data;
     surface->width = width;
     surface->height = height;
     surface->linesize = linesize;
     surface->pf = pf;
-    if (surface->flags & QEMU_ALLOCATED_FLAG) {
-        data = g_realloc(surface->data,
-                         surface->linesize * surface->height);
-    } else {
-        data = g_malloc(surface->linesize * surface->height);
-    }
-    surface->data = (uint8_t *)data;
+
+    qemu_pixman_image_unref(surface->image);
+    surface->image = NULL;
+    surface->data = NULL;
+
+    surface->format = qemu_pixman_get_format(&pf);
+    assert(surface->format != 0);
+    surface->image = pixman_image_create_bits(surface->format,
+                                              width, height,
+                                              NULL, linesize);
+    assert(surface->image != NULL);
+
+    surface->data = (uint8_t *)pixman_image_get_data(surface->image);
     surface->flags = newflags | QEMU_ALLOCATED_FLAG;
 #ifdef HOST_WORDS_BIGENDIAN
     surface->flags |= QEMU_BIG_ENDIAN_FLAG;
@@ -1338,14 +1343,22 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
 }
 
 DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
-                                              int linesize, uint8_t *data)
+                                                int linesize, uint8_t *data)
 {
-    DisplaySurface *surface = (DisplaySurface*) g_malloc0(sizeof(DisplaySurface));
+    DisplaySurface *surface = g_new0(DisplaySurface, 1);
 
     surface->width = width;
     surface->height = height;
     surface->linesize = linesize;
     surface->pf = qemu_default_pixelformat(bpp);
+
+    surface->format = qemu_pixman_get_format(&surface->pf);
+    assert(surface->format != 0);
+    surface->image = pixman_image_create_bits(surface->format,
+                                              width, height,
+                                              (void *)data, linesize);
+    assert(surface->image != NULL);
+
 #ifdef HOST_WORDS_BIGENDIAN
     surface->flags = QEMU_BIG_ENDIAN_FLAG;
 #endif
@@ -1360,9 +1373,7 @@ void qemu_free_displaysurface(DisplayState *ds)
     if (ds->surface == NULL) {
         return;
     }
-    if (ds->surface->flags & QEMU_ALLOCATED_FLAG) {
-        g_free(ds->surface->data);
-    }
+    qemu_pixman_image_unref(ds->surface->image);
     g_free(ds->surface);
 }
 
diff --git a/console.h b/console.h
index 6be880a..f19e6a4 100644
--- a/console.h
+++ b/console.h
@@ -2,6 +2,7 @@
 #define CONSOLE_H
 
 #include "qemu-char.h"
+#include "qemu-pixman.h"
 #include "qdict.h"
 #include "notify.h"
 #include "monitor.h"
@@ -119,6 +120,8 @@ struct PixelFormat {
 };
 
 struct DisplaySurface {
+    pixman_format_code_t format;
+    pixman_image_t *image;
     uint8_t flags;
     int width;
     int height;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 14/22] console: make qemu_alloc_display static
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (12 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 13/22] pixman: add pixman image to DisplaySurface Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 15/22] console: don't set PixelFormat alpha fields for 32bpp Gerd Hoffmann
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c |   48 ++++++++++++++++++++++++------------------------
 console.h |    2 --
 2 files changed, 24 insertions(+), 26 deletions(-)

diff --git a/console.c b/console.c
index 5e1c5f5..48d88e4 100644
--- a/console.c
+++ b/console.c
@@ -1294,30 +1294,8 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
     return s;
 }
 
-DisplaySurface *qemu_create_displaysurface(DisplayState *ds,
-                                           int width, int height)
-{
-    DisplaySurface *surface = g_new0(DisplaySurface, 1);
-
-    int linesize = width * 4;
-    qemu_alloc_display(surface, width, height, linesize,
-                       qemu_default_pixelformat(32), 0);
-    return surface;
-}
-
-DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
-                                           int width, int height)
-{
-    int linesize = width * 4;
-
-    trace_displaysurface_resize(ds, ds->surface, width, height);
-    qemu_alloc_display(ds->surface, width, height, linesize,
-                       qemu_default_pixelformat(32), 0);
-    return ds->surface;
-}
-
-void qemu_alloc_display(DisplaySurface *surface, int width, int height,
-                        int linesize, PixelFormat pf, int newflags)
+static void qemu_alloc_display(DisplaySurface *surface, int width, int height,
+                               int linesize, PixelFormat pf, int newflags)
 {
     surface->width = width;
     surface->height = height;
@@ -1342,6 +1320,28 @@ void qemu_alloc_display(DisplaySurface *surface, int width, int height,
 #endif
 }
 
+DisplaySurface *qemu_create_displaysurface(DisplayState *ds,
+                                           int width, int height)
+{
+    DisplaySurface *surface = g_new0(DisplaySurface, 1);
+
+    int linesize = width * 4;
+    qemu_alloc_display(surface, width, height, linesize,
+                       qemu_default_pixelformat(32), 0);
+    return surface;
+}
+
+DisplaySurface *qemu_resize_displaysurface(DisplayState *ds,
+                                           int width, int height)
+{
+    int linesize = width * 4;
+
+    trace_displaysurface_resize(ds, ds->surface, width, height);
+    qemu_alloc_display(ds->surface, width, height, linesize,
+                       qemu_default_pixelformat(32), 0);
+    return ds->surface;
+}
+
 DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
                                                 int linesize, uint8_t *data)
 {
diff --git a/console.h b/console.h
index f19e6a4..21bd957 100644
--- a/console.h
+++ b/console.h
@@ -190,8 +190,6 @@ void register_displaystate(DisplayState *ds);
 DisplayState *get_displaystate(void);
 DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
                                                 int linesize, uint8_t *data);
-void qemu_alloc_display(DisplaySurface *surface, int width, int height,
-                        int linesize, PixelFormat pf, int newflags);
 PixelFormat qemu_different_endianness_pixelformat(int bpp);
 PixelFormat qemu_default_pixelformat(int bpp);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 15/22] console: don't set PixelFormat alpha fields for 32bpp
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (13 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 14/22] console: make qemu_alloc_display static Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 16/22] qxl: stop direct access to DisplaySurface fields Gerd Hoffmann
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Currently it is inconstent, PixelFormat->amask is left unset whereas
abits and amax and ashift are filled.  As an alpha channel doesn't make
sense for the vga framebuffer leave all alpha fields clear.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/console.c b/console.c
index 48d88e4..d28b75e 100644
--- a/console.c
+++ b/console.c
@@ -1715,18 +1715,15 @@ PixelFormat qemu_default_pixelformat(int bpp)
             pf.rmask = 0x00FF0000;
             pf.gmask = 0x0000FF00;
             pf.bmask = 0x000000FF;
-            pf.amax = 255;
             pf.rmax = 255;
             pf.gmax = 255;
             pf.bmax = 255;
-            pf.ashift = 24;
             pf.rshift = 16;
             pf.gshift = 8;
             pf.bshift = 0;
             pf.rbits = 8;
             pf.gbits = 8;
             pf.bbits = 8;
-            pf.abits = 8;
             break;
         default:
             break;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 16/22] qxl: stop direct access to DisplaySurface fields.
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (14 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 15/22] console: don't set PixelFormat alpha fields for 32bpp Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 17/22] vga: " Gerd Hoffmann
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl-render.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 47eb8b4..98ecb21 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -24,7 +24,7 @@
 static void qxl_blit(PCIQXLDevice *qxl, QXLRect *rect)
 {
     uint8_t *src;
-    uint8_t *dst = qxl->vga.ds->surface->data;
+    uint8_t *dst = ds_get_data(qxl->vga.ds);
     int len, i;
 
     if (is_buffer_shared(qxl->vga.ds->surface)) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 17/22] vga: stop direct access to DisplaySurface fields.
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (15 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 16/22] qxl: stop direct access to DisplaySurface fields Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 18/22] pixman: switch screendump function Gerd Hoffmann
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/vga.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/vga.c b/hw/vga.c
index f31dbdd..1188463 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1709,8 +1709,13 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         s->last_depth = depth;
         full_update = 1;
     } else if (is_buffer_shared(s->ds->surface) &&
-               (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
-        s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
+               (full_update || ds_get_data(s->ds) != s->vram_ptr
+                + (s->start_addr * 4))) {
+        qemu_free_displaysurface(s->ds);
+        s->ds->surface = qemu_create_displaysurface_from(disp_width,
+                height, depth,
+                s->line_offset,
+                s->vram_ptr + (s->start_addr * 4));
         dpy_gfx_setdata(s->ds);
     }
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 18/22] pixman: switch screendump function.
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (16 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 17/22] vga: " Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 19/22] pixman/vnc: use pixman images in vnc Gerd Hoffmann
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/vga.c |   39 +++++++++++----------------------------
 1 files changed, 11 insertions(+), 28 deletions(-)

diff --git a/hw/vga.c b/hw/vga.c
index 1188463..023134e 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2393,13 +2393,12 @@ void vga_init_vbe(VGACommonState *s, MemoryRegion *system_memory)
 
 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;
-    uint8_t *d, *d1;
-    uint32_t v;
-    int y, x;
-    uint8_t r, g, b;
+    int y;
     int ret;
-    char *linebuf, *pbuf;
+    pixman_image_t *linebuf;
 
     trace_ppm_save(filename, ds);
     f = fopen(filename, "wb");
@@ -2408,33 +2407,17 @@ void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
                    strerror(errno));
         return;
     }
-    ret = fprintf(f, "P6\n%d %d\n%d\n", ds->width, ds->height, 255);
+    ret = fprintf(f, "P6\n%d %d\n%d\n", width, height, 255);
     if (ret < 0) {
         linebuf = NULL;
         goto write_err;
     }
-    linebuf = g_malloc(ds->width * 3);
-    d1 = ds->data;
-    for(y = 0; y < ds->height; y++) {
-        d = d1;
-        pbuf = linebuf;
-        for(x = 0; x < ds->width; x++) {
-            if (ds->pf.bits_per_pixel == 32)
-                v = *(uint32_t *)d;
-            else
-                v = (uint32_t) (*(uint16_t *)d);
-            /* Limited to 8 or fewer bits per channel: */
-            r = ((v >> ds->pf.rshift) & ds->pf.rmax) << (8 - ds->pf.rbits);
-            g = ((v >> ds->pf.gshift) & ds->pf.gmax) << (8 - ds->pf.gbits);
-            b = ((v >> ds->pf.bshift) & ds->pf.bmax) << (8 - ds->pf.bbits);
-            *pbuf++ = r;
-            *pbuf++ = g;
-            *pbuf++ = b;
-            d += ds->pf.bytes_per_pixel;
-        }
-        d1 += ds->linesize;
+    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, width);
+    for (y = 0; y < height; y++) {
+        qemu_pixman_linebuf_fill(linebuf, ds->image, width, y);
         clearerr(f);
-        ret = fwrite(linebuf, 1, pbuf - linebuf, f);
+        ret = fwrite(pixman_image_get_data(linebuf), 1,
+                     pixman_image_get_stride(linebuf), f);
         (void)ret;
         if (ferror(f)) {
             goto write_err;
@@ -2442,7 +2425,7 @@ void ppm_save(const char *filename, struct DisplaySurface *ds, Error **errp)
     }
 
 out:
-    g_free(linebuf);
+    qemu_pixman_image_unref(linebuf);
     fclose(f);
     return;
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 19/22] pixman/vnc: use pixman images in vnc.
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (17 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 18/22] pixman: switch screendump function Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 20/22] pixman/vnc: remove rgb_prepare_row* functions Gerd Hoffmann
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

The vnc code uses *three* DisplaySurfaces:

First is the surface of the actual QemuConsole, usually the guest
screen, but could also be a text console (monitor/serial reachable via
Ctrl-Alt-<nr> keys).  This is left as-is.

Second is the current server's view of the screen content.  The vnc code
uses this to figure which parts of the guest screen did _really_ change
to reduce the amount of updates sent to the vnc clients.  It is also
used as data source when sending out the updates to the clients.  This
surface gets replaced by a pixman image.  The format changes too,
instead of using the guest screen format we'll use fixed 32bit rgb
framebuffer and convert the pixels on the fly when comparing and
updating the server framebuffer.

Third surface carries the format expected by the vnc client.  That isn't
used to store image data.  This surface is switched to PixelFormat and a
boolean for bigendian byte order.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/vnc-enc-hextile-template.h |   23 ++--
 ui/vnc-enc-hextile.c          |   45 ++++----
 ui/vnc-enc-tight.c            |  144 ++++++++++++-------------
 ui/vnc-enc-zrle.c             |   18 ++--
 ui/vnc-jobs.c                 |    3 +-
 ui/vnc.c                      |  235 +++++++++++++++++++++++------------------
 ui/vnc.h                      |   19 +++-
 7 files changed, 259 insertions(+), 228 deletions(-)

diff --git a/ui/vnc-enc-hextile-template.h b/ui/vnc-enc-hextile-template.h
index a7310e1..d868d75 100644
--- a/ui/vnc-enc-hextile-template.h
+++ b/ui/vnc-enc-hextile-template.h
@@ -14,7 +14,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
                                              int *has_bg, int *has_fg)
 {
     VncDisplay *vd = vs->vd;
-    uint8_t *row = vd->server->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
+    uint8_t *row = vnc_server_fb_ptr(vd, x, y);
     pixel_t *irow = (pixel_t *)row;
     int j, i;
     pixel_t *last_bg = (pixel_t *)last_bg_;
@@ -25,7 +25,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
     int bg_count = 0;
     int fg_count = 0;
     int flags = 0;
-    uint8_t data[(vs->clientds.pf.bytes_per_pixel + 2) * 16 * 16];
+    uint8_t data[(vs->client_pf.bytes_per_pixel + 2) * 16 * 16];
     int n_data = 0;
     int n_subtiles = 0;
 
@@ -58,7 +58,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
 	}
 	if (n_colors > 2)
 	    break;
-	irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
+	irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
     }
 
     if (n_colors > 1 && fg_count > bg_count) {
@@ -106,7 +106,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
 		n_data += 2;
 		n_subtiles++;
 	    }
-	    irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
+	    irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
 	}
 	break;
     case 3:
@@ -133,7 +133,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
 		    has_color = 0;
 #ifdef GENERIC
                     vnc_convert_pixel(vs, data + n_data, color);
-                    n_data += vs->clientds.pf.bytes_per_pixel;
+                    n_data += vs->client_pf.bytes_per_pixel;
 #else
 		    memcpy(data + n_data, &color, sizeof(color));
                     n_data += sizeof(pixel_t);
@@ -153,7 +153,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
 	    if (has_color) {
 #ifdef GENERIC
                 vnc_convert_pixel(vs, data + n_data, color);
-                n_data += vs->clientds.pf.bytes_per_pixel;
+                n_data += vs->client_pf.bytes_per_pixel;
 #else
                 memcpy(data + n_data, &color, sizeof(color));
                 n_data += sizeof(pixel_t);
@@ -162,7 +162,7 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
 		n_data += 2;
 		n_subtiles++;
 	    }
-	    irow += ds_get_linesize(vs->ds) / sizeof(pixel_t);
+	    irow += vnc_server_fb_stride(vd) / sizeof(pixel_t);
 	}
 
 	/* A SubrectsColoured subtile invalidates the foreground color */
@@ -190,18 +190,17 @@ static void CONCAT(send_hextile_tile_, NAME)(VncState *vs,
     vnc_write_u8(vs, flags);
     if (n_colors < 4) {
 	if (flags & 0x02)
-	    vs->write_pixels(vs, &vd->server->pf, last_bg, sizeof(pixel_t));
+	    vs->write_pixels(vs, last_bg, sizeof(pixel_t));
 	if (flags & 0x04)
-	    vs->write_pixels(vs, &vd->server->pf, last_fg, sizeof(pixel_t));
+	    vs->write_pixels(vs, last_fg, sizeof(pixel_t));
 	if (n_subtiles) {
 	    vnc_write_u8(vs, n_subtiles);
 	    vnc_write(vs, data, n_data);
 	}
     } else {
 	for (j = 0; j < h; j++) {
-	    vs->write_pixels(vs, &vd->server->pf, row,
-                             w * ds_get_bytes_per_pixel(vs->ds));
-	    row += ds_get_linesize(vs->ds);
+	    vs->write_pixels(vs, row, w * 4);
+	    row += vnc_server_fb_stride(vd);
 	}
     }
 }
diff --git a/ui/vnc-enc-hextile.c b/ui/vnc-enc-hextile.c
index c860dbb..263a0ce 100644
--- a/ui/vnc-enc-hextile.c
+++ b/ui/vnc-enc-hextile.c
@@ -68,10 +68,9 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
     int i, j;
     int has_fg, has_bg;
     uint8_t *last_fg, *last_bg;
-    VncDisplay *vd = vs->vd;
 
-    last_fg = (uint8_t *) g_malloc(vd->server->pf.bytes_per_pixel);
-    last_bg = (uint8_t *) g_malloc(vd->server->pf.bytes_per_pixel);
+    last_fg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES);
+    last_bg = (uint8_t *) g_malloc(VNC_SERVER_FB_BYTES);
     has_fg = has_bg = 0;
     for (j = y; j < (y + h); j += 16) {
         for (i = x; i < (x + w); i += 16) {
@@ -89,28 +88,28 @@ int vnc_hextile_send_framebuffer_update(VncState *vs, int x,
 void vnc_hextile_set_pixel_conversion(VncState *vs, int generic)
 {
     if (!generic) {
-        switch (vs->ds->surface->pf.bits_per_pixel) {
-            case 8:
-                vs->hextile.send_tile = send_hextile_tile_8;
-                break;
-            case 16:
-                vs->hextile.send_tile = send_hextile_tile_16;
-                break;
-            case 32:
-                vs->hextile.send_tile = send_hextile_tile_32;
-                break;
+        switch (VNC_SERVER_FB_BITS) {
+        case 8:
+            vs->hextile.send_tile = send_hextile_tile_8;
+            break;
+        case 16:
+            vs->hextile.send_tile = send_hextile_tile_16;
+            break;
+        case 32:
+            vs->hextile.send_tile = send_hextile_tile_32;
+            break;
         }
     } else {
-        switch (vs->ds->surface->pf.bits_per_pixel) {
-            case 8:
-                vs->hextile.send_tile = send_hextile_tile_generic_8;
-                break;
-            case 16:
-                vs->hextile.send_tile = send_hextile_tile_generic_16;
-                break;
-            case 32:
-                vs->hextile.send_tile = send_hextile_tile_generic_32;
-                break;
+        switch (VNC_SERVER_FB_BITS) {
+        case 8:
+            vs->hextile.send_tile = send_hextile_tile_generic_8;
+            break;
+        case 16:
+            vs->hextile.send_tile = send_hextile_tile_generic_16;
+            break;
+        case 32:
+            vs->hextile.send_tile = send_hextile_tile_generic_32;
+            break;
         }
     }
 }
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 5d492ab..8013c5c 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -124,7 +124,7 @@ static bool tight_can_send_png_rect(VncState *vs, int w, int h)
     }
 
     if (ds_get_bytes_per_pixel(vs->ds) == 1 ||
-        vs->clientds.pf.bytes_per_pixel == 1) {
+        vs->client_pf.bytes_per_pixel == 1) {
         return false;
     }
 
@@ -153,7 +153,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h)
      * If client is big-endian, color samples begin from the second
      * byte (offset 1) of a 32-bit pixel value.
      */
-    off = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG);
+    off = vs->client_be;
 
     memset(stats, 0, sizeof (stats));
 
@@ -216,16 +216,16 @@ tight_detect_smooth_image24(VncState *vs, int w, int h)
         unsigned int errors;                                            \
         unsigned char *buf = vs->tight.tight.buffer;                    \
                                                                         \
-        endian = ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) !=        \
-                  (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG));     \
+        endian = 0; /* FIXME: ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \
+                      (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); */ \
                                                                         \
                                                                         \
-        max[0] = vs->clientds.pf.rmax;                                  \
-        max[1] = vs->clientds.pf.gmax;                                  \
-        max[2] = vs->clientds.pf.bmax;                                  \
-        shift[0] = vs->clientds.pf.rshift;                              \
-        shift[1] = vs->clientds.pf.gshift;                              \
-        shift[2] = vs->clientds.pf.bshift;                              \
+        max[0] = vs->client_pf.rmax;                                  \
+        max[1] = vs->client_pf.gmax;                                  \
+        max[2] = vs->client_pf.bmax;                                  \
+        shift[0] = vs->client_pf.rshift;                              \
+        shift[1] = vs->client_pf.gshift;                              \
+        shift[2] = vs->client_pf.bshift;                              \
                                                                         \
         memset(stats, 0, sizeof(stats));                                \
                                                                         \
@@ -302,7 +302,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
     }
 
     if (ds_get_bytes_per_pixel(vs->ds) == 1 ||
-        vs->clientds.pf.bytes_per_pixel == 1 ||
+        vs->client_pf.bytes_per_pixel == 1 ||
         w < VNC_TIGHT_DETECT_MIN_WIDTH || h < VNC_TIGHT_DETECT_MIN_HEIGHT) {
         return 0;
     }
@@ -317,7 +317,7 @@ tight_detect_smooth_image(VncState *vs, int w, int h)
         }
     }
 
-    if (vs->clientds.pf.bytes_per_pixel == 4) {
+    if (vs->client_pf.bytes_per_pixel == 4) {
         if (vs->tight.pixel24) {
             errors = tight_detect_smooth_image24(vs, w, h);
             if (vs->tight.quality != (uint8_t)-1) {
@@ -430,7 +430,7 @@ static int tight_fill_palette(VncState *vs, int x, int y,
         max = 256;
     }
 
-    switch(vs->clientds.pf.bytes_per_pixel) {
+    switch (vs->client_pf.bytes_per_pixel) {
     case 4:
         return tight_fill_palette32(vs, x, y, max, count, bg, fg, palette);
     case 2:
@@ -557,15 +557,15 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
     buf32 = (uint32_t *)buf;
     memset(vs->tight.gradient.buffer, 0, w * 3 * sizeof(int));
 
-    if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
-        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)) {
-        shift[0] = vs->clientds.pf.rshift;
-        shift[1] = vs->clientds.pf.gshift;
-        shift[2] = vs->clientds.pf.bshift;
+    if (1 /* FIXME: (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
+             (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) */) {
+        shift[0] = vs->client_pf.rshift;
+        shift[1] = vs->client_pf.gshift;
+        shift[2] = vs->client_pf.bshift;
     } else {
-        shift[0] = 24 - vs->clientds.pf.rshift;
-        shift[1] = 24 - vs->clientds.pf.gshift;
-        shift[2] = 24 - vs->clientds.pf.bshift;
+        shift[0] = 24 - vs->client_pf.rshift;
+        shift[1] = 24 - vs->client_pf.gshift;
+        shift[2] = 24 - vs->client_pf.bshift;
     }
 
     for (y = 0; y < h; y++) {
@@ -615,15 +615,15 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
                                                                         \
         memset (vs->tight.gradient.buffer, 0, w * 3 * sizeof(int));     \
                                                                         \
-        endian = ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) !=        \
-                  (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG));     \
+        endian = 0; /* FIXME: ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \
+                       (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); */ \
                                                                         \
-        max[0] = vs->clientds.pf.rmax;                                  \
-        max[1] = vs->clientds.pf.gmax;                                  \
-        max[2] = vs->clientds.pf.bmax;                                  \
-        shift[0] = vs->clientds.pf.rshift;                              \
-        shift[1] = vs->clientds.pf.gshift;                              \
-        shift[2] = vs->clientds.pf.bshift;                              \
+        max[0] = vs->client_pf.rmax;                                    \
+        max[1] = vs->client_pf.gmax;                                    \
+        max[2] = vs->client_pf.bmax;                                    \
+        shift[0] = vs->client_pf.rshift;                                \
+        shift[1] = vs->client_pf.gshift;                                \
+        shift[2] = vs->client_pf.bshift;                                \
                                                                         \
         for (y = 0; y < h; y++) {                                       \
             for (c = 0; c < 3; c++) {                                   \
@@ -682,9 +682,7 @@ DEFINE_GRADIENT_FILTER_FUNCTION(32)
         uint##bpp##_t c;                                                \
         int dx, dy;                                                     \
                                                                         \
-        fbptr = (uint##bpp##_t *)                                       \
-            (vd->server->data + y * ds_get_linesize(vs->ds) +           \
-             x * ds_get_bytes_per_pixel(vs->ds));                       \
+        fbptr = vnc_server_fb_ptr(vd, x, y);                            \
                                                                         \
         c = *fbptr;                                                     \
         if (samecolor && (uint32_t)c != *color) {                       \
@@ -698,7 +696,7 @@ DEFINE_GRADIENT_FILTER_FUNCTION(32)
                 }                                                       \
             }                                                           \
             fbptr = (uint##bpp##_t *)                                   \
-                ((uint8_t *)fbptr + ds_get_linesize(vs->ds));           \
+                ((uint8_t *)fbptr + vnc_server_fb_stride(vd));          \
         }                                                               \
                                                                         \
         *color = (uint32_t)c;                                           \
@@ -712,9 +710,7 @@ DEFINE_CHECK_SOLID_FUNCTION(8)
 static bool check_solid_tile(VncState *vs, int x, int y, int w, int h,
                              uint32_t* color, bool samecolor)
 {
-    VncDisplay *vd = vs->vd;
-
-    switch(vd->server->pf.bytes_per_pixel) {
+    switch (VNC_SERVER_FB_BYTES) {
     case 4:
         return check_solid_tile32(vs, x, y, w, h, color, samecolor);
     case 2:
@@ -906,15 +902,15 @@ static void tight_pack24(VncState *vs, uint8_t *buf, size_t count, size_t *ret)
 
     buf32 = (uint32_t *)buf;
 
-    if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
-        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)) {
-        rshift = vs->clientds.pf.rshift;
-        gshift = vs->clientds.pf.gshift;
-        bshift = vs->clientds.pf.bshift;
+    if (1 /* FIXME: (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
+             (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) */) {
+        rshift = vs->client_pf.rshift;
+        gshift = vs->client_pf.gshift;
+        bshift = vs->client_pf.bshift;
     } else {
-        rshift = 24 - vs->clientds.pf.rshift;
-        gshift = 24 - vs->clientds.pf.gshift;
-        bshift = 24 - vs->clientds.pf.bshift;
+        rshift = 24 - vs->client_pf.rshift;
+        gshift = 24 - vs->client_pf.gshift;
+        bshift = 24 - vs->client_pf.bshift;
     }
 
     if (ret) {
@@ -946,7 +942,7 @@ static int send_full_color_rect(VncState *vs, int x, int y, int w, int h)
         tight_pack24(vs, vs->tight.tight.buffer, w * h, &vs->tight.tight.offset);
         bytes = 3;
     } else {
-        bytes = vs->clientds.pf.bytes_per_pixel;
+        bytes = vs->client_pf.bytes_per_pixel;
     }
 
     bytes = tight_compress_data(vs, stream, w * h * bytes,
@@ -966,7 +962,7 @@ static int send_solid_rect(VncState *vs)
         tight_pack24(vs, vs->tight.tight.buffer, 1, &vs->tight.tight.offset);
         bytes = 3;
     } else {
-        bytes = vs->clientds.pf.bytes_per_pixel;
+        bytes = vs->client_pf.bytes_per_pixel;
     }
 
     vnc_write(vs, vs->tight.tight.buffer, bytes);
@@ -983,7 +979,7 @@ static int send_mono_rect(VncState *vs, int x, int y,
 #ifdef CONFIG_VNC_PNG
     if (tight_can_send_png_rect(vs, w, h)) {
         int ret;
-        int bpp = vs->clientds.pf.bytes_per_pixel * 8;
+        int bpp = vs->client_pf.bytes_per_pixel * 8;
         VncPalette *palette = palette_new(2, bpp);
 
         palette_put(palette, bg);
@@ -1000,7 +996,7 @@ static int send_mono_rect(VncState *vs, int x, int y,
     vnc_write_u8(vs, VNC_TIGHT_FILTER_PALETTE);
     vnc_write_u8(vs, 1);
 
-    switch(vs->clientds.pf.bytes_per_pixel) {
+    switch (vs->client_pf.bytes_per_pixel) {
     case 4:
     {
         uint32_t buf[2] = {bg, fg};
@@ -1043,7 +1039,7 @@ static void write_palette(int idx, uint32_t color, void *opaque)
 {
     struct palette_cb_priv *priv = opaque;
     VncState *vs = priv->vs;
-    uint32_t bytes = vs->clientds.pf.bytes_per_pixel;
+    uint32_t bytes = vs->client_pf.bytes_per_pixel;
 
     if (bytes == 4) {
         ((uint32_t*)priv->header)[idx] = color;
@@ -1058,8 +1054,9 @@ static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h)
     int level = tight_conf[vs->tight.compression].gradient_zlib_level;
     ssize_t bytes;
 
-    if (vs->clientds.pf.bytes_per_pixel == 1)
+    if (vs->client_pf.bytes_per_pixel == 1) {
         return send_full_color_rect(vs, x, y, w, h);
+    }
 
     vnc_write_u8(vs, (stream | VNC_TIGHT_EXPLICIT_FILTER) << 4);
     vnc_write_u8(vs, VNC_TIGHT_FILTER_GRADIENT);
@@ -1069,7 +1066,7 @@ static bool send_gradient_rect(VncState *vs, int x, int y, int w, int h)
     if (vs->tight.pixel24) {
         tight_filter_gradient24(vs, vs->tight.tight.buffer, w, h);
         bytes = 3;
-    } else if (vs->clientds.pf.bytes_per_pixel == 4) {
+    } else if (vs->client_pf.bytes_per_pixel == 4) {
         tight_filter_gradient32(vs, (uint32_t *)vs->tight.tight.buffer, w, h);
         bytes = 4;
     } else {
@@ -1107,7 +1104,7 @@ static int send_palette_rect(VncState *vs, int x, int y,
     vnc_write_u8(vs, VNC_TIGHT_FILTER_PALETTE);
     vnc_write_u8(vs, colors - 1);
 
-    switch(vs->clientds.pf.bytes_per_pixel) {
+    switch (vs->client_pf.bytes_per_pixel) {
     case 4:
     {
         size_t old_offset, offset;
@@ -1156,8 +1153,7 @@ static void rgb_prepare_row24(VncState *vs, uint8_t *dst, int x, int y,
     uint32_t *fbptr;
     uint32_t pix;
 
-    fbptr = (uint32_t *)(vd->server->data + y * ds_get_linesize(vs->ds) +
-                         x * ds_get_bytes_per_pixel(vs->ds));
+    fbptr = vnc_server_fb_ptr(vd, x, y);
 
     while (count--) {
         pix = *fbptr++;
@@ -1178,9 +1174,7 @@ static void rgb_prepare_row24(VncState *vs, uint8_t *dst, int x, int y,
         uint##bpp##_t pix;                                              \
         int r, g, b;                                                    \
                                                                         \
-        fbptr = (uint##bpp##_t *)                                       \
-            (vd->server->data + y * ds_get_linesize(vs->ds) +           \
-             x * ds_get_bytes_per_pixel(vs->ds));                       \
+        fbptr = vnc_server_fb_ptr(vd, x, y);                            \
                                                                         \
         while (count--) {                                               \
             pix = *fbptr++;                                             \
@@ -1207,10 +1201,8 @@ DEFINE_RGB_GET_ROW_FUNCTION(32)
 static void rgb_prepare_row(VncState *vs, uint8_t *dst, int x, int y,
                             int count)
 {
-    if (ds_get_bytes_per_pixel(vs->ds) == 4) {
-        if (vs->ds->surface->pf.rmax == 0xFF &&
-            vs->ds->surface->pf.gmax == 0xFF &&
-            vs->ds->surface->pf.bmax == 0xFF) {
+    if (VNC_SERVER_FB_BYTES == 4) {
+        if (1) {
             rgb_prepare_row24(vs, dst, x, y, count);
         } else {
             rgb_prepare_row32(vs, dst, x, y, count);
@@ -1326,23 +1318,23 @@ static void write_png_palette(int idx, uint32_t pix, void *opaque)
 
     if (vs->tight.pixel24)
     {
-        color->red = (pix >> vs->clientds.pf.rshift) & vs->clientds.pf.rmax;
-        color->green = (pix >> vs->clientds.pf.gshift) & vs->clientds.pf.gmax;
-        color->blue = (pix >> vs->clientds.pf.bshift) & vs->clientds.pf.bmax;
+        color->red = (pix >> vs->client_pf.rshift) & vs->client_pf.rmax;
+        color->green = (pix >> vs->client_pf.gshift) & vs->client_pf.gmax;
+        color->blue = (pix >> vs->client_pf.bshift) & vs->client_pf.bmax;
     }
     else
     {
         int red, green, blue;
 
-        red = (pix >> vs->clientds.pf.rshift) & vs->clientds.pf.rmax;
-        green = (pix >> vs->clientds.pf.gshift) & vs->clientds.pf.gmax;
-        blue = (pix >> vs->clientds.pf.bshift) & vs->clientds.pf.bmax;
-        color->red = ((red * 255 + vs->clientds.pf.rmax / 2) /
-                      vs->clientds.pf.rmax);
-        color->green = ((green * 255 + vs->clientds.pf.gmax / 2) /
-                        vs->clientds.pf.gmax);
-        color->blue = ((blue * 255 + vs->clientds.pf.bmax / 2) /
-                       vs->clientds.pf.bmax);
+        red = (pix >> vs->client_pf.rshift) & vs->client_pf.rmax;
+        green = (pix >> vs->client_pf.gshift) & vs->client_pf.gmax;
+        blue = (pix >> vs->client_pf.bshift) & vs->client_pf.bmax;
+        color->red = ((red * 255 + vs->client_pf.rmax / 2) /
+                      vs->client_pf.rmax);
+        color->green = ((green * 255 + vs->client_pf.gmax / 2) /
+                        vs->client_pf.gmax);
+        color->blue = ((blue * 255 + vs->client_pf.bmax / 2) /
+                       vs->client_pf.bmax);
     }
 }
 
@@ -1422,7 +1414,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
 
         png_set_PLTE(png_ptr, info_ptr, png_palette, palette_size(palette));
 
-        if (vs->clientds.pf.bytes_per_pixel == 4) {
+        if (vs->client_pf.bytes_per_pixel == 4) {
             tight_encode_indexed_rect32(vs->tight.tight.buffer, w * h, palette);
         } else {
             tight_encode_indexed_rect16(vs->tight.tight.buffer, w * h, palette);
@@ -1713,8 +1705,8 @@ static int tight_send_framebuffer_update(VncState *vs, int x, int y,
 {
     int max_rows;
 
-    if (vs->clientds.pf.bytes_per_pixel == 4 && vs->clientds.pf.rmax == 0xFF &&
-        vs->clientds.pf.bmax == 0xFF && vs->clientds.pf.gmax == 0xFF) {
+    if (vs->client_pf.bytes_per_pixel == 4 && vs->client_pf.rmax == 0xFF &&
+        vs->client_pf.bmax == 0xFF && vs->client_pf.gmax == 0xFF) {
         vs->tight.pixel24 = true;
     } else {
         vs->tight.pixel24 = false;
diff --git a/ui/vnc-enc-zrle.c b/ui/vnc-enc-zrle.c
index 917d384..ed3b484 100644
--- a/ui/vnc-enc-zrle.c
+++ b/ui/vnc-enc-zrle.c
@@ -255,7 +255,7 @@ static void zrle_write_u8(VncState *vs, uint8_t value)
 static int zrle_send_framebuffer_update(VncState *vs, int x, int y,
                                         int w, int h)
 {
-    bool be = !!(vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG);
+    bool be = vs->client_be;
     size_t bytes;
     int zywrle_level;
 
@@ -277,13 +277,13 @@ static int zrle_send_framebuffer_update(VncState *vs, int x, int y,
 
     vnc_zrle_start(vs);
 
-    switch(vs->clientds.pf.bytes_per_pixel) {
+    switch (vs->client_pf.bytes_per_pixel) {
     case 1:
         zrle_encode_8ne(vs, x, y, w, h, zywrle_level);
         break;
 
     case 2:
-        if (vs->clientds.pf.gmax > 0x1F) {
+        if (vs->client_pf.gmax > 0x1F) {
             if (be) {
                 zrle_encode_16be(vs, x, y, w, h, zywrle_level);
             } else {
@@ -304,13 +304,13 @@ static int zrle_send_framebuffer_update(VncState *vs, int x, int y,
         bool fits_in_ms3bytes;
 
         fits_in_ls3bytes =
-            ((vs->clientds.pf.rmax << vs->clientds.pf.rshift) < (1 << 24) &&
-             (vs->clientds.pf.gmax << vs->clientds.pf.gshift) < (1 << 24) &&
-             (vs->clientds.pf.bmax << vs->clientds.pf.bshift) < (1 << 24));
+            ((vs->client_pf.rmax << vs->client_pf.rshift) < (1 << 24) &&
+             (vs->client_pf.gmax << vs->client_pf.gshift) < (1 << 24) &&
+             (vs->client_pf.bmax << vs->client_pf.bshift) < (1 << 24));
 
-        fits_in_ms3bytes = (vs->clientds.pf.rshift > 7 &&
-                            vs->clientds.pf.gshift > 7 &&
-                            vs->clientds.pf.bshift > 7);
+        fits_in_ms3bytes = (vs->client_pf.rshift > 7 &&
+                            vs->client_pf.gshift > 7 &&
+                            vs->client_pf.bshift > 7);
 
         if ((fits_in_ls3bytes && !be) || (fits_in_ms3bytes && be)) {
             if (be) {
diff --git a/ui/vnc-jobs.c b/ui/vnc-jobs.c
index 3c592b3..04f139b 100644
--- a/ui/vnc-jobs.c
+++ b/ui/vnc-jobs.c
@@ -187,7 +187,8 @@ static void vnc_async_encoding_start(VncState *orig, VncState *local)
     local->vd = orig->vd;
     local->lossy_rect = orig->lossy_rect;
     local->write_pixels = orig->write_pixels;
-    local->clientds = orig->clientds;
+    local->client_pf = orig->client_pf;
+    local->client_be = orig->client_be;
     local->tight = orig->tight;
     local->zlib = orig->zlib;
     local->hextile = orig->hextile;
diff --git a/ui/vnc.c b/ui/vnc.c
index 0ae1c74..15aef86 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -436,6 +436,8 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
     int i;
     VncDisplay *vd = ds->opaque;
     struct VncSurface *s = &vd->guest;
+    int width = ds_get_width(ds);
+    int height = ds_get_height(ds);
 
     h += y;
 
@@ -446,10 +448,10 @@ static void vnc_dpy_update(DisplayState *ds, int x, int y, int w, int h)
     w += (x % 16);
     x -= (x % 16);
 
-    x = MIN(x, s->ds->width);
-    y = MIN(y, s->ds->height);
-    w = MIN(x + w, s->ds->width) - x;
-    h = MIN(h, s->ds->height);
+    x = MIN(x, width);
+    y = MIN(y, height);
+    w = MIN(x + w, width) - x;
+    h = MIN(h, height);
 
     for (; y < h; y++)
         for (i = 0; i < w; i += 16)
@@ -550,6 +552,21 @@ static void vnc_abort_display_jobs(VncDisplay *vd)
     }
 }
 
+int vnc_server_fb_stride(VncDisplay *vd)
+{
+    return pixman_image_get_stride(vd->server);
+}
+
+void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y)
+{
+    uint8_t *ptr;
+
+    ptr  = (uint8_t *)pixman_image_get_data(vd->server);
+    ptr += y * vnc_server_fb_stride(vd);
+    ptr += x * VNC_SERVER_FB_BYTES;
+    return ptr;
+}
+
 static void vnc_dpy_resize(DisplayState *ds)
 {
     VncDisplay *vd = ds->opaque;
@@ -558,20 +575,20 @@ static void vnc_dpy_resize(DisplayState *ds)
     vnc_abort_display_jobs(vd);
 
     /* server surface */
-    if (!vd->server)
-        vd->server = g_malloc0(sizeof(*vd->server));
-    if (vd->server->data)
-        g_free(vd->server->data);
-    *(vd->server) = *(ds->surface);
-    vd->server->data = g_malloc0(vd->server->linesize *
-                                    vd->server->height);
+    qemu_pixman_image_unref(vd->server);
+    vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT,
+                                          ds_get_width(ds),
+                                          ds_get_height(ds),
+                                          NULL, 0);
 
     /* guest surface */
-    if (!vd->guest.ds)
-        vd->guest.ds = g_malloc0(sizeof(*vd->guest.ds));
+#if 0 /* FIXME */
     if (ds_get_bytes_per_pixel(ds) != vd->guest.ds->pf.bytes_per_pixel)
         console_color_init(ds);
-    *(vd->guest.ds) = *(ds->surface);
+#endif
+    qemu_pixman_image_unref(vd->guest.fb);
+    vd->guest.fb = pixman_image_ref(ds->surface->image);
+    vd->guest.format = ds->surface->format;
     memset(vd->guest.dirty, 0xFF, sizeof(vd->guest.dirty));
 
     QTAILQ_FOREACH(vs, &vd->clients, next) {
@@ -585,7 +602,7 @@ static void vnc_dpy_resize(DisplayState *ds)
 }
 
 /* fastest code */
-static void vnc_write_pixels_copy(VncState *vs, struct PixelFormat *pf,
+static void vnc_write_pixels_copy(VncState *vs,
                                   void *pixels, int size)
 {
     vnc_write(vs, pixels, size);
@@ -595,23 +612,23 @@ static void vnc_write_pixels_copy(VncState *vs, struct PixelFormat *pf,
 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
 {
     uint8_t r, g, b;
-    VncDisplay *vd = vs->vd;
 
-    r = ((((v & vd->server->pf.rmask) >> vd->server->pf.rshift) << vs->clientds.pf.rbits) >>
-        vd->server->pf.rbits);
-    g = ((((v & vd->server->pf.gmask) >> vd->server->pf.gshift) << vs->clientds.pf.gbits) >>
-        vd->server->pf.gbits);
-    b = ((((v & vd->server->pf.bmask) >> vd->server->pf.bshift) << vs->clientds.pf.bbits) >>
-        vd->server->pf.bbits);
-    v = (r << vs->clientds.pf.rshift) |
-        (g << vs->clientds.pf.gshift) |
-        (b << vs->clientds.pf.bshift);
-    switch(vs->clientds.pf.bytes_per_pixel) {
+#if VNC_SERVER_FB_FORMAT == PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
+    r = (((v & 0x00ff0000) >> 16) << vs->client_pf.rbits) >> 8;
+    g = (((v & 0x0000ff00) >>  8) << vs->client_pf.gbits) >> 8;
+    b = (((v & 0x000000ff) >>  0) << vs->client_pf.bbits) >> 8;
+#else
+# error need some bits here if you change VNC_SERVER_FB_FORMAT
+#endif
+    v = (r << vs->client_pf.rshift) |
+        (g << vs->client_pf.gshift) |
+        (b << vs->client_pf.bshift);
+    switch (vs->client_pf.bytes_per_pixel) {
     case 1:
         buf[0] = v;
         break;
     case 2:
-        if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
+        if (vs->client_be) {
             buf[0] = v >> 8;
             buf[1] = v;
         } else {
@@ -621,7 +638,7 @@ void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
         break;
     default:
     case 4:
-        if (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) {
+        if (vs->client_be) {
             buf[0] = v >> 24;
             buf[1] = v >> 16;
             buf[2] = v >> 8;
@@ -636,37 +653,37 @@ void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v)
     }
 }
 
-static void vnc_write_pixels_generic(VncState *vs, struct PixelFormat *pf,
+static void vnc_write_pixels_generic(VncState *vs,
                                      void *pixels1, int size)
 {
     uint8_t buf[4];
 
-    if (pf->bytes_per_pixel == 4) {
+    if (VNC_SERVER_FB_BYTES == 4) {
         uint32_t *pixels = pixels1;
         int n, i;
         n = size >> 2;
-        for(i = 0; i < n; i++) {
+        for (i = 0; i < n; i++) {
             vnc_convert_pixel(vs, buf, pixels[i]);
-            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
+            vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
         }
-    } else if (pf->bytes_per_pixel == 2) {
+    } else if (VNC_SERVER_FB_BYTES == 2) {
         uint16_t *pixels = pixels1;
         int n, i;
         n = size >> 1;
-        for(i = 0; i < n; i++) {
+        for (i = 0; i < n; i++) {
             vnc_convert_pixel(vs, buf, pixels[i]);
-            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
+            vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
         }
-    } else if (pf->bytes_per_pixel == 1) {
+    } else if (VNC_SERVER_FB_BYTES == 1) {
         uint8_t *pixels = pixels1;
         int n, i;
         n = size;
-        for(i = 0; i < n; i++) {
+        for (i = 0; i < n; i++) {
             vnc_convert_pixel(vs, buf, pixels[i]);
-            vnc_write(vs, buf, vs->clientds.pf.bytes_per_pixel);
+            vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
         }
     } else {
-        fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n");
+        fprintf(stderr, "%s: VncState color depth not supported\n", __func__);
     }
 }
 
@@ -676,10 +693,10 @@ int vnc_raw_send_framebuffer_update(VncState *vs, int x, int y, int w, int h)
     uint8_t *row;
     VncDisplay *vd = vs->vd;
 
-    row = vd->server->data + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);
+    row = vnc_server_fb_ptr(vd, x, y);
     for (i = 0; i < h; i++) {
-        vs->write_pixels(vs, &vd->server->pf, row, w * ds_get_bytes_per_pixel(vs->ds));
-        row += ds_get_linesize(vs->ds);
+        vs->write_pixels(vs, row, w * VNC_SERVER_FB_BYTES);
+        row += vnc_server_fb_stride(vd);
     }
     return 1;
 }
@@ -736,7 +753,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
     VncState *vs, *vn;
     uint8_t *src_row;
     uint8_t *dst_row;
-    int i,x,y,pitch,depth,inc,w_lim,s;
+    int i, x, y, pitch, inc, w_lim, s;
     int cmp_bytes;
 
     vnc_refresh_server_surface(vd);
@@ -749,10 +766,9 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
     }
 
     /* do bitblit op on the local surface too */
-    pitch = ds_get_linesize(vd->ds);
-    depth = ds_get_bytes_per_pixel(vd->ds);
-    src_row = vd->server->data + pitch * src_y + depth * src_x;
-    dst_row = vd->server->data + pitch * dst_y + depth * dst_x;
+    pitch = vnc_server_fb_stride(vd);
+    src_row = vnc_server_fb_ptr(vd, src_x, src_y);
+    dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
     y = dst_y;
     inc = 1;
     if (dst_y > src_y) {
@@ -780,7 +796,7 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
             } else {
                 s = 16;
             }
-            cmp_bytes = s * depth;
+            cmp_bytes = s * VNC_SERVER_FB_BYTES;
             if (memcmp(src_row, dst_row, cmp_bytes) == 0)
                 continue;
             memmove(dst_row, src_row, cmp_bytes);
@@ -790,8 +806,8 @@ static void vnc_dpy_copy(DisplayState *ds, int src_x, int src_y, int dst_x, int
                 }
             }
         }
-        src_row += pitch - w * depth;
-        dst_row += pitch - w * depth;
+        src_row += pitch - w * VNC_SERVER_FB_BYTES;
+        dst_row += pitch - w * VNC_SERVER_FB_BYTES;
         y += inc;
     }
 
@@ -810,7 +826,6 @@ static void vnc_mouse_set(DisplayState *ds, int x, int y, int visible)
 static int vnc_cursor_define(VncState *vs)
 {
     QEMUCursor *c = vs->vd->cursor;
-    PixelFormat pf = qemu_default_pixelformat(32);
     int isize;
 
     if (vnc_has_feature(vs, VNC_FEATURE_RICH_CURSOR)) {
@@ -820,8 +835,8 @@ static int vnc_cursor_define(VncState *vs)
         vnc_write_u16(vs, 1);  /*  # of rects  */
         vnc_framebuffer_update(vs, c->hot_x, c->hot_y, c->width, c->height,
                                VNC_ENCODING_RICH_CURSOR);
-        isize = c->width * c->height * vs->clientds.pf.bytes_per_pixel;
-        vnc_write_pixels_generic(vs, &pf, c->data, isize);
+        isize = c->width * c->height * vs->client_pf.bytes_per_pixel;
+        vnc_write_pixels_generic(vs, c->data, isize);
         vnc_write(vs, vs->vd->cursor_mask, vs->vd->cursor_msize);
         vnc_unlock_output(vs);
         return 0;
@@ -898,8 +913,8 @@ static int vnc_update_client(VncState *vs, int has_dirty)
          */
         job = vnc_job_new(vs);
 
-        width = MIN(vd->server->width, vs->client_width);
-        height = MIN(vd->server->height, vs->client_height);
+        width = MIN(pixman_image_get_width(vd->server), vs->client_width);
+        height = MIN(pixman_image_get_height(vd->server), vs->client_height);
 
         for (y = 0; y < height; y++) {
             int x;
@@ -1861,9 +1876,9 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
 
 static void set_pixel_conversion(VncState *vs)
 {
-    if ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
-        (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) && 
-        !memcmp(&(vs->clientds.pf), &(vs->ds->surface->pf), sizeof(PixelFormat))) {
+    pixman_format_code_t fmt = qemu_pixman_get_format(&vs->client_pf);
+
+    if (fmt == VNC_SERVER_FB_FORMAT) {
         vs->write_pixels = vnc_write_pixels_copy;
         vnc_hextile_set_pixel_conversion(vs, 0);
     } else {
@@ -1883,23 +1898,22 @@ static void set_pixel_format(VncState *vs,
         return;
     }
 
-    vs->clientds = *(vs->vd->guest.ds);
-    vs->clientds.pf.rmax = red_max;
-    vs->clientds.pf.rbits = hweight_long(red_max);
-    vs->clientds.pf.rshift = red_shift;
-    vs->clientds.pf.rmask = red_max << red_shift;
-    vs->clientds.pf.gmax = green_max;
-    vs->clientds.pf.gbits = hweight_long(green_max);
-    vs->clientds.pf.gshift = green_shift;
-    vs->clientds.pf.gmask = green_max << green_shift;
-    vs->clientds.pf.bmax = blue_max;
-    vs->clientds.pf.bbits = hweight_long(blue_max);
-    vs->clientds.pf.bshift = blue_shift;
-    vs->clientds.pf.bmask = blue_max << blue_shift;
-    vs->clientds.pf.bits_per_pixel = bits_per_pixel;
-    vs->clientds.pf.bytes_per_pixel = bits_per_pixel / 8;
-    vs->clientds.pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
-    vs->clientds.flags = big_endian_flag ? QEMU_BIG_ENDIAN_FLAG : 0x00;
+    vs->client_pf.rmax = red_max;
+    vs->client_pf.rbits = hweight_long(red_max);
+    vs->client_pf.rshift = red_shift;
+    vs->client_pf.rmask = red_max << red_shift;
+    vs->client_pf.gmax = green_max;
+    vs->client_pf.gbits = hweight_long(green_max);
+    vs->client_pf.gshift = green_shift;
+    vs->client_pf.gmask = green_max << green_shift;
+    vs->client_pf.bmax = blue_max;
+    vs->client_pf.bbits = hweight_long(blue_max);
+    vs->client_pf.bshift = blue_shift;
+    vs->client_pf.bmask = blue_max << blue_shift;
+    vs->client_pf.bits_per_pixel = bits_per_pixel;
+    vs->client_pf.bytes_per_pixel = bits_per_pixel / 8;
+    vs->client_pf.depth = bits_per_pixel == 32 ? 24 : bits_per_pixel;
+    vs->client_be = big_endian_flag;
 
     set_pixel_conversion(vs);
 
@@ -1910,8 +1924,10 @@ static void set_pixel_format(VncState *vs,
 static void pixel_format_message (VncState *vs) {
     char pad[3] = { 0, 0, 0 };
 
-    vnc_write_u8(vs, vs->ds->surface->pf.bits_per_pixel); /* bits-per-pixel */
-    vnc_write_u8(vs, vs->ds->surface->pf.depth); /* depth */
+    vs->client_pf = qemu_default_pixelformat(32);
+
+    vnc_write_u8(vs, vs->client_pf.bits_per_pixel); /* bits-per-pixel */
+    vnc_write_u8(vs, vs->client_pf.depth); /* depth */
 
 #ifdef HOST_WORDS_BIGENDIAN
     vnc_write_u8(vs, 1);             /* big-endian-flag */
@@ -1919,27 +1935,25 @@ static void pixel_format_message (VncState *vs) {
     vnc_write_u8(vs, 0);             /* big-endian-flag */
 #endif
     vnc_write_u8(vs, 1);             /* true-color-flag */
-    vnc_write_u16(vs, vs->ds->surface->pf.rmax);     /* red-max */
-    vnc_write_u16(vs, vs->ds->surface->pf.gmax);     /* green-max */
-    vnc_write_u16(vs, vs->ds->surface->pf.bmax);     /* blue-max */
-    vnc_write_u8(vs, vs->ds->surface->pf.rshift);    /* red-shift */
-    vnc_write_u8(vs, vs->ds->surface->pf.gshift);    /* green-shift */
-    vnc_write_u8(vs, vs->ds->surface->pf.bshift);    /* blue-shift */
+    vnc_write_u16(vs, vs->client_pf.rmax);     /* red-max */
+    vnc_write_u16(vs, vs->client_pf.gmax);     /* green-max */
+    vnc_write_u16(vs, vs->client_pf.bmax);     /* blue-max */
+    vnc_write_u8(vs, vs->client_pf.rshift);    /* red-shift */
+    vnc_write_u8(vs, vs->client_pf.gshift);    /* green-shift */
+    vnc_write_u8(vs, vs->client_pf.bshift);    /* blue-shift */
+    vnc_write(vs, pad, 3);           /* padding */
 
     vnc_hextile_set_pixel_conversion(vs, 0);
-
-    vs->clientds = *(vs->ds->surface);
-    vs->clientds.flags &= ~QEMU_ALLOCATED_FLAG;
     vs->write_pixels = vnc_write_pixels_copy;
-
-    vnc_write(vs, pad, 3);           /* padding */
 }
 
 static void vnc_dpy_setdata(DisplayState *ds)
 {
     VncDisplay *vd = ds->opaque;
 
-    *(vd->guest.ds) = *(ds->surface);
+    qemu_pixman_image_unref(vd->guest.fb);
+    vd->guest.fb = pixman_image_ref(ds->surface->image);
+    vd->guest.format = ds->surface->format;
     vnc_dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
 }
 
@@ -2443,12 +2457,14 @@ static int vnc_refresh_lossy_rect(VncDisplay *vd, int x, int y)
 
 static int vnc_update_stats(VncDisplay *vd,  struct timeval * tv)
 {
+    int width = pixman_image_get_width(vd->guest.fb);
+    int height = pixman_image_get_height(vd->guest.fb);
     int x, y;
     struct timeval res;
     int has_dirty = 0;
 
-    for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) {
-        for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) {
+    for (y = 0; y < height; y += VNC_STAT_RECT) {
+        for (x = 0; x < width; x += VNC_STAT_RECT) {
             VncRectStat *rect = vnc_stat_rect(vd, x, y);
 
             rect->updated = false;
@@ -2462,8 +2478,8 @@ static int vnc_update_stats(VncDisplay *vd,  struct timeval * tv)
     }
     vd->guest.last_freq_check = *tv;
 
-    for (y = 0; y < vd->guest.ds->height; y += VNC_STAT_RECT) {
-        for (x = 0; x < vd->guest.ds->width; x += VNC_STAT_RECT) {
+    for (y = 0; y < height; y += VNC_STAT_RECT) {
+        for (x = 0; x < width; x += VNC_STAT_RECT) {
             VncRectStat *rect= vnc_stat_rect(vd, x, y);
             int count = ARRAY_SIZE(rect->times);
             struct timeval min, max;
@@ -2532,12 +2548,15 @@ static void vnc_rect_updated(VncDisplay *vd, int x, int y, struct timeval * tv)
 
 static int vnc_refresh_server_surface(VncDisplay *vd)
 {
+    int width = pixman_image_get_width(vd->guest.fb);
+    int height = pixman_image_get_height(vd->guest.fb);
     int y;
     uint8_t *guest_row;
     uint8_t *server_row;
     int cmp_bytes;
     VncState *vs;
     int has_dirty = 0;
+    pixman_image_t *tmpbuf = NULL;
 
     struct timeval tv = { 0, 0 };
 
@@ -2551,22 +2570,31 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
      * Check and copy modified bits from guest to server surface.
      * Update server dirty map.
      */
-    cmp_bytes = 16 * ds_get_bytes_per_pixel(vd->ds);
-    if (cmp_bytes > vd->ds->surface->linesize) {
-        cmp_bytes = vd->ds->surface->linesize;
+    cmp_bytes = 64;
+    if (cmp_bytes > vnc_server_fb_stride(vd)) {
+        cmp_bytes = vnc_server_fb_stride(vd);
+    }
+    if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
+        int width = pixman_image_get_width(vd->server);
+        tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
     }
-    guest_row  = vd->guest.ds->data;
-    server_row = vd->server->data;
-    for (y = 0; y < vd->guest.ds->height; y++) {
+    guest_row = (uint8_t *)pixman_image_get_data(vd->guest.fb);
+    server_row = (uint8_t *)pixman_image_get_data(vd->server);
+    for (y = 0; y < height; y++) {
         if (!bitmap_empty(vd->guest.dirty[y], VNC_DIRTY_BITS)) {
             int x;
             uint8_t *guest_ptr;
             uint8_t *server_ptr;
 
-            guest_ptr  = guest_row;
+            if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
+                qemu_pixman_linebuf_fill(tmpbuf, vd->guest.fb, width, y);
+                guest_ptr = (uint8_t *)pixman_image_get_data(tmpbuf);
+            } else {
+                guest_ptr = guest_row;
+            }
             server_ptr = server_row;
 
-            for (x = 0; x + 15 < vd->guest.ds->width;
+            for (x = 0; x + 15 < width;
                     x += 16, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) {
                 if (!test_and_clear_bit((x / 16), vd->guest.dirty[y]))
                     continue;
@@ -2581,9 +2609,10 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
                 has_dirty++;
             }
         }
-        guest_row  += ds_get_linesize(vd->ds);
-        server_row += ds_get_linesize(vd->ds);
+        guest_row  += pixman_image_get_stride(vd->guest.fb);
+        server_row += pixman_image_get_stride(vd->server);
     }
+    qemu_pixman_image_unref(tmpbuf);
     return has_dirty;
 }
 
diff --git a/ui/vnc.h b/ui/vnc.h
index 068c2fc..d003afb 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -69,7 +69,7 @@ typedef struct VncRectEntry VncRectEntry;
 
 typedef int VncReadEvent(VncState *vs, uint8_t *data, size_t len);
 
-typedef void VncWritePixels(VncState *vs, struct PixelFormat *pf, void *data, int size);
+typedef void VncWritePixels(VncState *vs, void *data, int size);
 
 typedef void VncSendHextileTile(VncState *vs,
                                 int x, int y, int w, int h,
@@ -117,7 +117,8 @@ struct VncSurface
     struct timeval last_freq_check;
     DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_MAX_WIDTH / 16);
     VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS];
-    DisplaySurface *ds;
+    pixman_image_t *fb;
+    pixman_format_code_t format;
 };
 
 typedef enum VncShareMode {
@@ -151,7 +152,7 @@ struct VncDisplay
     uint8_t *cursor_mask;
 
     struct VncSurface guest;   /* guest visible surface (aka ds->surface) */
-    DisplaySurface *server;  /* vnc server surface */
+    pixman_image_t *server;    /* vnc server surface */
 
     char *display;
     char *password;
@@ -275,7 +276,9 @@ struct VncState
     Buffer input;
     /* current output mode information */
     VncWritePixels *write_pixels;
-    DisplaySurface clientds;
+    PixelFormat client_pf;
+    pixman_format_code_t client_format;
+    bool client_be;
 
     CaptureVoiceOut *audio_cap;
     struct audsettings as;
@@ -527,6 +530,14 @@ static inline uint32_t vnc_has_feature(VncState *vs, int feature) {
 void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h,
                             int32_t encoding);
 
+/* server fb is in PIXMAN_x8r8g8b8 */
+#define VNC_SERVER_FB_FORMAT PIXMAN_FORMAT(32, PIXMAN_TYPE_ARGB, 0, 8, 8, 8)
+#define VNC_SERVER_FB_BITS   (PIXMAN_FORMAT_BPP(VNC_SERVER_FB_FORMAT))
+#define VNC_SERVER_FB_BYTES  ((VNC_SERVER_FB_BITS+7)/8)
+
+void *vnc_server_fb_ptr(VncDisplay *vd, int x, int y);
+int vnc_server_fb_stride(VncDisplay *vd);
+
 void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v);
 double vnc_update_freq(VncState *vs, int x, int y, int w, int h);
 void vnc_sent_lossy_rect(VncState *vs, int x, int y, int w, int h);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 20/22] pixman/vnc: remove rgb_prepare_row* functions
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (18 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 19/22] pixman/vnc: use pixman images in vnc Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 21/22] pixman/vnc: remove dead code Gerd Hoffmann
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Let pixman do it instead.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/vnc-enc-tight.c |   84 ++++++---------------------------------------------
 1 files changed, 10 insertions(+), 74 deletions(-)

diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 8013c5c..9fd2556 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -1145,74 +1145,6 @@ static int send_palette_rect(VncState *vs, int x, int y,
     return (bytes >= 0);
 }
 
-#if defined(CONFIG_VNC_JPEG) || defined(CONFIG_VNC_PNG)
-static void rgb_prepare_row24(VncState *vs, uint8_t *dst, int x, int y,
-                              int count)
-{
-    VncDisplay *vd = vs->vd;
-    uint32_t *fbptr;
-    uint32_t pix;
-
-    fbptr = vnc_server_fb_ptr(vd, x, y);
-
-    while (count--) {
-        pix = *fbptr++;
-        *dst++ = (uint8_t)(pix >> vs->ds->surface->pf.rshift);
-        *dst++ = (uint8_t)(pix >> vs->ds->surface->pf.gshift);
-        *dst++ = (uint8_t)(pix >> vs->ds->surface->pf.bshift);
-    }
-}
-
-#define DEFINE_RGB_GET_ROW_FUNCTION(bpp)                                \
-                                                                        \
-    static void                                                         \
-    rgb_prepare_row##bpp(VncState *vs, uint8_t *dst,                    \
-                         int x, int y, int count)                       \
-    {                                                                   \
-        VncDisplay *vd = vs->vd;                                        \
-        uint##bpp##_t *fbptr;                                           \
-        uint##bpp##_t pix;                                              \
-        int r, g, b;                                                    \
-                                                                        \
-        fbptr = vnc_server_fb_ptr(vd, x, y);                            \
-                                                                        \
-        while (count--) {                                               \
-            pix = *fbptr++;                                             \
-                                                                        \
-            r = (int)((pix >> vs->ds->surface->pf.rshift)               \
-                      & vs->ds->surface->pf.rmax);                      \
-            g = (int)((pix >> vs->ds->surface->pf.gshift)               \
-                      & vs->ds->surface->pf.gmax);                      \
-            b = (int)((pix >> vs->ds->surface->pf.bshift)               \
-                      & vs->ds->surface->pf.bmax);                      \
-                                                                        \
-            *dst++ = (uint8_t)((r * 255 + vs->ds->surface->pf.rmax / 2) \
-                               / vs->ds->surface->pf.rmax);             \
-            *dst++ = (uint8_t)((g * 255 + vs->ds->surface->pf.gmax / 2) \
-                               / vs->ds->surface->pf.gmax);             \
-            *dst++ = (uint8_t)((b * 255 + vs->ds->surface->pf.bmax / 2) \
-                               / vs->ds->surface->pf.bmax);             \
-        }                                                               \
-    }
-
-DEFINE_RGB_GET_ROW_FUNCTION(16)
-DEFINE_RGB_GET_ROW_FUNCTION(32)
-
-static void rgb_prepare_row(VncState *vs, uint8_t *dst, int x, int y,
-                            int count)
-{
-    if (VNC_SERVER_FB_BYTES == 4) {
-        if (1) {
-            rgb_prepare_row24(vs, dst, x, y, count);
-        } else {
-            rgb_prepare_row32(vs, dst, x, y, count);
-        }
-    } else {
-        rgb_prepare_row16(vs, dst, x, y, count);
-    }
-}
-#endif /* CONFIG_VNC_JPEG or CONFIG_VNC_PNG */
-
 /*
  * JPEG compression stuff.
  */
@@ -1257,6 +1189,7 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
     struct jpeg_compress_struct cinfo;
     struct jpeg_error_mgr jerr;
     struct jpeg_destination_mgr manager;
+    pixman_image_t *linebuf;
     JSAMPROW row[1];
     uint8_t *buf;
     int dy;
@@ -1285,13 +1218,14 @@ static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality)
 
     jpeg_start_compress(&cinfo, true);
 
-    buf = g_malloc(w * 3);
+    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w);
+    buf = (uint8_t *)pixman_image_get_data(linebuf);
     row[0] = buf;
     for (dy = 0; dy < h; dy++) {
-        rgb_prepare_row(vs, buf, x, y + dy, w);
+        qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, dy);
         jpeg_write_scanlines(&cinfo, row, 1);
     }
-    g_free(buf);
+    qemu_pixman_image_unref(linebuf);
 
     jpeg_finish_compress(&cinfo);
     jpeg_destroy_compress(&cinfo);
@@ -1370,6 +1304,7 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
     png_structp png_ptr;
     png_infop info_ptr;
     png_colorp png_palette = NULL;
+    pixman_image_t *linebuf;
     int level = tight_png_conf[vs->tight.compression].png_zlib_level;
     int filters = tight_png_conf[vs->tight.compression].png_filters;
     uint8_t *buf;
@@ -1424,17 +1359,18 @@ static int send_png_rect(VncState *vs, int x, int y, int w, int h,
     png_write_info(png_ptr, info_ptr);
 
     buffer_reserve(&vs->tight.png, 2048);
-    buf = g_malloc(w * 3);
+    linebuf = qemu_pixman_linebuf_create(PIXMAN_BE_r8g8b8, w);
+    buf = (uint8_t *)pixman_image_get_data(linebuf);
     for (dy = 0; dy < h; dy++)
     {
         if (color_type == PNG_COLOR_TYPE_PALETTE) {
             memcpy(buf, vs->tight.tight.buffer + (dy * w), w);
         } else {
-            rgb_prepare_row(vs, buf, x, y + dy, w);
+            qemu_pixman_linebuf_fill(linebuf, vs->vd->server, w, dy);
         }
         png_write_row(png_ptr, buf);
     }
-    g_free(buf);
+    qemu_pixman_image_unref(linebuf);
 
     png_write_end(png_ptr, NULL);
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 21/22] pixman/vnc: remove dead code.
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (19 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 20/22] pixman/vnc: remove rgb_prepare_row* functions Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 22/22] pixman: drop obsolete fields from DisplaySurface Gerd Hoffmann
  2012-11-01 19:33 ` [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Anthony Liguori
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Switching the vnc server framebuffer to use 32bpp unconditionally
turns the code bits which handle 8 and 16 bpp into dead code.
Remove them.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/vnc-enc-hextile.c |   32 -------------------------
 ui/vnc-enc-tight.c   |   64 +++++++++++++++++++++-----------------------------
 ui/vnc.c             |   18 --------------
 3 files changed, 27 insertions(+), 87 deletions(-)

diff --git a/ui/vnc-enc-hextile.c b/ui/vnc-enc-hextile.c
index 263a0ce..2e768fd 100644
--- a/ui/vnc-enc-hextile.c
+++ b/ui/vnc-enc-hextile.c
@@ -32,31 +32,11 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h)
     ptr[1] = (((w - 1) & 0x0F) << 4) | ((h - 1) & 0x0F);
 }
 
-#define BPP 8
-#include "vnc-enc-hextile-template.h"
-#undef BPP
-
-#define BPP 16
-#include "vnc-enc-hextile-template.h"
-#undef BPP
-
 #define BPP 32
 #include "vnc-enc-hextile-template.h"
 #undef BPP
 
 #define GENERIC
-#define BPP 8
-#include "vnc-enc-hextile-template.h"
-#undef BPP
-#undef GENERIC
-
-#define GENERIC
-#define BPP 16
-#include "vnc-enc-hextile-template.h"
-#undef BPP
-#undef GENERIC
-
-#define GENERIC
 #define BPP 32
 #include "vnc-enc-hextile-template.h"
 #undef BPP
@@ -89,24 +69,12 @@ void vnc_hextile_set_pixel_conversion(VncState *vs, int generic)
 {
     if (!generic) {
         switch (VNC_SERVER_FB_BITS) {
-        case 8:
-            vs->hextile.send_tile = send_hextile_tile_8;
-            break;
-        case 16:
-            vs->hextile.send_tile = send_hextile_tile_16;
-            break;
         case 32:
             vs->hextile.send_tile = send_hextile_tile_32;
             break;
         }
     } else {
         switch (VNC_SERVER_FB_BITS) {
-        case 8:
-            vs->hextile.send_tile = send_hextile_tile_generic_8;
-            break;
-        case 16:
-            vs->hextile.send_tile = send_hextile_tile_generic_16;
-            break;
         case 32:
             vs->hextile.send_tile = send_hextile_tile_generic_32;
             break;
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 9fd2556..9ae4cab 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -671,41 +671,35 @@ DEFINE_GRADIENT_FILTER_FUNCTION(32)
  * that case new color will be stored in *colorPtr.
  */
 
-#define DEFINE_CHECK_SOLID_FUNCTION(bpp)                                \
-                                                                        \
-    static bool                                                         \
-    check_solid_tile##bpp(VncState *vs, int x, int y, int w, int h,     \
-                          uint32_t* color, bool samecolor)              \
-    {                                                                   \
-        VncDisplay *vd = vs->vd;                                        \
-        uint##bpp##_t *fbptr;                                           \
-        uint##bpp##_t c;                                                \
-        int dx, dy;                                                     \
-                                                                        \
-        fbptr = vnc_server_fb_ptr(vd, x, y);                            \
-                                                                        \
-        c = *fbptr;                                                     \
-        if (samecolor && (uint32_t)c != *color) {                       \
-            return false;                                               \
-        }                                                               \
-                                                                        \
-        for (dy = 0; dy < h; dy++) {                                    \
-            for (dx = 0; dx < w; dx++) {                                \
-                if (c != fbptr[dx]) {                                   \
-                    return false;                                       \
-                }                                                       \
-            }                                                           \
-            fbptr = (uint##bpp##_t *)                                   \
-                ((uint8_t *)fbptr + vnc_server_fb_stride(vd));          \
-        }                                                               \
-                                                                        \
-        *color = (uint32_t)c;                                           \
-        return true;                                                    \
+static bool
+check_solid_tile32(VncState *vs, int x, int y, int w, int h,
+                   uint32_t *color, bool samecolor)
+{
+    VncDisplay *vd = vs->vd;
+    uint32_t *fbptr;
+    uint32_t c;
+    int dx, dy;
+
+    fbptr = vnc_server_fb_ptr(vd, x, y);
+
+    c = *fbptr;
+    if (samecolor && (uint32_t)c != *color) {
+        return false;
     }
 
-DEFINE_CHECK_SOLID_FUNCTION(32)
-DEFINE_CHECK_SOLID_FUNCTION(16)
-DEFINE_CHECK_SOLID_FUNCTION(8)
+    for (dy = 0; dy < h; dy++) {
+        for (dx = 0; dx < w; dx++) {
+            if (c != fbptr[dx]) {
+                return false;
+            }
+        }
+        fbptr = (uint32_t *)
+            ((uint8_t *)fbptr + vnc_server_fb_stride(vd));
+    }
+
+    *color = (uint32_t)c;
+    return true;
+}
 
 static bool check_solid_tile(VncState *vs, int x, int y, int w, int h,
                              uint32_t* color, bool samecolor)
@@ -713,10 +707,6 @@ static bool check_solid_tile(VncState *vs, int x, int y, int w, int h,
     switch (VNC_SERVER_FB_BYTES) {
     case 4:
         return check_solid_tile32(vs, x, y, w, h, color, samecolor);
-    case 2:
-        return check_solid_tile16(vs, x, y, w, h, color, samecolor);
-    default:
-        return check_solid_tile8(vs, x, y, w, h, color, samecolor);
     }
 }
 
diff --git a/ui/vnc.c b/ui/vnc.c
index 15aef86..7c120e6 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -666,24 +666,6 @@ static void vnc_write_pixels_generic(VncState *vs,
             vnc_convert_pixel(vs, buf, pixels[i]);
             vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
         }
-    } else if (VNC_SERVER_FB_BYTES == 2) {
-        uint16_t *pixels = pixels1;
-        int n, i;
-        n = size >> 1;
-        for (i = 0; i < n; i++) {
-            vnc_convert_pixel(vs, buf, pixels[i]);
-            vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
-        }
-    } else if (VNC_SERVER_FB_BYTES == 1) {
-        uint8_t *pixels = pixels1;
-        int n, i;
-        n = size;
-        for (i = 0; i < n; i++) {
-            vnc_convert_pixel(vs, buf, pixels[i]);
-            vnc_write(vs, buf, vs->client_pf.bytes_per_pixel);
-        }
-    } else {
-        fprintf(stderr, "%s: VncState color depth not supported\n", __func__);
     }
 }
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [Qemu-devel] [PATCH 22/22] pixman: drop obsolete fields from DisplaySurface
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (20 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 21/22] pixman/vnc: remove dead code Gerd Hoffmann
@ 2012-11-01 13:04 ` Gerd Hoffmann
  2012-11-01 19:33 ` [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Anthony Liguori
  22 siblings, 0 replies; 29+ messages in thread
From: Gerd Hoffmann @ 2012-11-01 13:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 console.c |    9 ---------
 console.h |   23 +++++++++++++----------
 2 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/console.c b/console.c
index d28b75e..048b48e 100644
--- a/console.c
+++ b/console.c
@@ -1297,14 +1297,10 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type)
 static void qemu_alloc_display(DisplaySurface *surface, int width, int height,
                                int linesize, PixelFormat pf, int newflags)
 {
-    surface->width = width;
-    surface->height = height;
-    surface->linesize = linesize;
     surface->pf = pf;
 
     qemu_pixman_image_unref(surface->image);
     surface->image = NULL;
-    surface->data = NULL;
 
     surface->format = qemu_pixman_get_format(&pf);
     assert(surface->format != 0);
@@ -1313,7 +1309,6 @@ static void qemu_alloc_display(DisplaySurface *surface, int width, int height,
                                               NULL, linesize);
     assert(surface->image != NULL);
 
-    surface->data = (uint8_t *)pixman_image_get_data(surface->image);
     surface->flags = newflags | QEMU_ALLOCATED_FLAG;
 #ifdef HOST_WORDS_BIGENDIAN
     surface->flags |= QEMU_BIG_ENDIAN_FLAG;
@@ -1347,9 +1342,6 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
 {
     DisplaySurface *surface = g_new0(DisplaySurface, 1);
 
-    surface->width = width;
-    surface->height = height;
-    surface->linesize = linesize;
     surface->pf = qemu_default_pixelformat(bpp);
 
     surface->format = qemu_pixman_get_format(&surface->pf);
@@ -1362,7 +1354,6 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
 #ifdef HOST_WORDS_BIGENDIAN
     surface->flags = QEMU_BIG_ENDIAN_FLAG;
 #endif
-    surface->data = data;
 
     return surface;
 }
diff --git a/console.h b/console.h
index 21bd957..33ad69b 100644
--- a/console.h
+++ b/console.h
@@ -123,10 +123,6 @@ struct DisplaySurface {
     pixman_format_code_t format;
     pixman_image_t *image;
     uint8_t flags;
-    int width;
-    int height;
-    int linesize;        /* bytes per line */
-    uint8_t *data;
 
     struct PixelFormat pf;
 };
@@ -346,32 +342,39 @@ static inline bool dpy_cursor_define_supported(struct DisplayState *s)
 
 static inline int ds_get_linesize(DisplayState *ds)
 {
-    return ds->surface->linesize;
+    return pixman_image_get_stride(ds->surface->image);
 }
 
 static inline uint8_t* ds_get_data(DisplayState *ds)
 {
-    return ds->surface->data;
+    return (void *)pixman_image_get_data(ds->surface->image);
 }
 
 static inline int ds_get_width(DisplayState *ds)
 {
-    return ds->surface->width;
+    return pixman_image_get_width(ds->surface->image);
 }
 
 static inline int ds_get_height(DisplayState *ds)
 {
-    return ds->surface->height;
+    return pixman_image_get_height(ds->surface->image);
 }
 
 static inline int ds_get_bits_per_pixel(DisplayState *ds)
 {
-    return ds->surface->pf.bits_per_pixel;
+    int bits = PIXMAN_FORMAT_BPP(ds->surface->format);
+    return bits;
 }
 
 static inline int ds_get_bytes_per_pixel(DisplayState *ds)
 {
-    return ds->surface->pf.bytes_per_pixel;
+    int bits = PIXMAN_FORMAT_BPP(ds->surface->format);
+    return (bits + 7) / 8;
+}
+
+static inline pixman_format_code_t ds_get_format(DisplayState *ds)
+{
+    return ds->surface->format;
 }
 
 #ifdef CONFIG_CURSES
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering
  2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
                   ` (21 preceding siblings ...)
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 22/22] pixman: drop obsolete fields from DisplaySurface Gerd Hoffmann
@ 2012-11-01 19:33 ` Anthony Liguori
  2012-11-02 16:14   ` Andreas Färber
  22 siblings, 1 reply; 29+ messages in thread
From: Anthony Liguori @ 2012-11-01 19:33 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

Gerd Hoffmann <kraxel@redhat.com> writes:

>   Hi,
>
> Sitting on these too long already.  Series has been on the list a while
> back, only splitted into two parts (separate "console cleanups" series
> carrying patches 1-8).  Patch 11 was updated according to Paolos
> suggestion, otherwise the patches are unmodified.
>
> please pull,
>   Gerd

Pulled. Thanks.

Regards,

Anthony Liguori

>
> The following changes since commit 286d52ebfc0d0d53c2a878e454292fea14bad41b:
>
>   target-mips: don't flush extra TLB on permissions upgrade (2012-10-31 22:20:49 +0100)
>
> are available in the git repository at:
>   git://git.kraxel.org/qemu pixman.v3
>
> Gerd Hoffmann (22):
>       console: QLIST-ify display change listeners.
>       console: add unregister_displaychangelistener
>       console: move set_mouse + cursor_define callbacks
>       console: s/TextConsole/QemuConsole/
>       console: untangle gfx & txt updates
>       console: init displaychangelisteners on register
>       vga: fix text mode updating
>       console: remove dpy_gfx_fill
>       console: remove DisplayAllocator
>       pixman: add submodule
>       pixman: windup in configure & makefiles
>       pixman: helper functions
>       pixman: add pixman image to DisplaySurface
>       console: make qemu_alloc_display static
>       console: don't set PixelFormat alpha fields for 32bpp
>       qxl: stop direct access to DisplaySurface fields.
>       vga: stop direct access to DisplaySurface fields.
>       pixman: switch screendump function.
>       pixman/vnc: use pixman images in vnc.
>       pixman/vnc: remove rgb_prepare_row* functions
>       pixman/vnc: remove dead code.
>       pixman: drop obsolete fields from DisplaySurface
>
>  .gitmodules                   |    3 +
>  Makefile                      |    9 ++
>  Makefile.objs                 |    1 +
>  configure                     |   38 ++++++
>  console.c                     |  240 +++++++++++++++++------------------
>  console.h                     |  229 ++++++++++++++++++++-------------
>  hw/blizzard.c                 |    4 +-
>  hw/exynos4210_fimd.c          |    2 +-
>  hw/g364fb.c                   |    7 +-
>  hw/jazz_led.c                 |    6 +-
>  hw/milkymist-vgafb.c          |    2 +-
>  hw/musicpal.c                 |    2 +-
>  hw/nseries.c                  |    2 +-
>  hw/omap_lcdc.c                |    2 +-
>  hw/palm.c                     |    2 +-
>  hw/pl110.c                    |    2 +-
>  hw/pxa2xx_lcd.c               |    8 +-
>  hw/qxl-render.c               |   14 +-
>  hw/qxl.c                      |    4 +-
>  hw/sm501.c                    |    4 +-
>  hw/ssd0303.c                  |    2 +-
>  hw/ssd0323.c                  |    2 +-
>  hw/tc6393xb.c                 |    4 +-
>  hw/tcx.c                      |   16 ++--
>  hw/vga.c                      |  111 +++++++++--------
>  hw/vga_int.h                  |    2 +
>  hw/vmware_vga.c               |   15 ++-
>  hw/xenfb.c                    |    2 +-
>  pixman                        |    1 +
>  qemu-common.h                 |    4 +-
>  qemu-pixman.c                 |   60 +++++++++
>  qemu-pixman.h                 |   32 +++++
>  ui/curses.c                   |   21 +--
>  ui/sdl.c                      |  140 ++------------------
>  ui/spice-display.c            |    8 +-
>  ui/vnc-enc-hextile-template.h |   23 ++--
>  ui/vnc-enc-hextile.c          |   53 ++-------
>  ui/vnc-enc-tight.c            |  280 +++++++++++++++--------------------------
>  ui/vnc-enc-zrle.c             |   18 ++--
>  ui/vnc-jobs.c                 |    3 +-
>  ui/vnc.c                      |  255 +++++++++++++++++++------------------
>  ui/vnc.h                      |   19 +++-
>  vl.c                          |   49 +++++--
>  43 files changed, 847 insertions(+), 854 deletions(-)
>  create mode 160000 pixman
>  create mode 100644 qemu-pixman.c
>  create mode 100644 qemu-pixman.h

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH 05/22] console: untangle gfx & txt updates
  2012-11-01 13:04 ` [Qemu-devel] [PATCH 05/22] console: untangle gfx & txt updates Gerd Hoffmann
@ 2012-11-02  7:20   ` Jan Kiszka
  2012-11-02 14:44     ` Peter Maydell
  0 siblings, 1 reply; 29+ messages in thread
From: Jan Kiszka @ 2012-11-02  7:20 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 37245 bytes --]

On 2012-11-01 14:04, Gerd Hoffmann wrote:
> Stop abusing displaysurface fields for text mode displays.
> (bpp = 0, width = cols, height = lines).
> 
> Add flags to displaystate indicating whenever text mode display
> (curses) or gfx mode displays (sdl, vnc, ...) are present.
> 
> Add separate displaychangelistener callbacks for text / gfx mode
> resize & updates.
> 
> This allows to enable gfx and txt diplays at the same time and also
> paves the way for more cleanups in the future.

Breaks building xenfb.c.

Jan

> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  console.c            |   59 +++++++++++++++++++++-------------------
>  console.h            |   74 +++++++++++++++++++++++++++++++++++---------------
>  hw/blizzard.c        |    4 +-
>  hw/exynos4210_fimd.c |    2 +-
>  hw/g364fb.c          |    7 +++--
>  hw/jazz_led.c        |    4 +-
>  hw/milkymist-vgafb.c |    2 +-
>  hw/musicpal.c        |    2 +-
>  hw/nseries.c         |    2 +-
>  hw/omap_lcdc.c       |    2 +-
>  hw/palm.c            |    2 +-
>  hw/pl110.c           |    2 +-
>  hw/pxa2xx_lcd.c      |    8 +++---
>  hw/qxl-render.c      |   10 +++---
>  hw/qxl.c             |    4 +-
>  hw/sm501.c           |    4 +-
>  hw/ssd0303.c         |    2 +-
>  hw/ssd0323.c         |    2 +-
>  hw/tc6393xb.c        |    4 +-
>  hw/tcx.c             |   16 +++++-----
>  hw/vga.c             |   34 ++++++++++-------------
>  hw/vmware_vga.c      |    4 +-
>  ui/curses.c          |   21 +++++---------
>  ui/sdl.c             |   12 ++++----
>  ui/spice-display.c   |    4 +-
>  ui/vnc.c             |    8 +++---
>  vl.c                 |   14 ++++++++-
>  27 files changed, 171 insertions(+), 138 deletions(-)
> 
> diff --git a/console.c b/console.c
> index b53dc1b..61812c7 100644
> --- a/console.c
> +++ b/console.c
> @@ -638,30 +638,33 @@ static void console_refresh(QemuConsole *s)
>  
>      if (s != active_console)
>          return;
> -    if (!ds_get_bits_per_pixel(s->ds)) {
> +
> +    if (s->ds->have_text) {
>          s->text_x[0] = 0;
>          s->text_y[0] = 0;
>          s->text_x[1] = s->width - 1;
>          s->text_y[1] = s->height - 1;
>          s->cursor_invalidate = 1;
> -        return;
>      }
>  
> -    vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
> -                  color_table[0][COLOR_BLACK]);
> -    y1 = s->y_displayed;
> -    for(y = 0; y < s->height; y++) {
> -        c = s->cells + y1 * s->width;
> -        for(x = 0; x < s->width; x++) {
> -            vga_putcharxy(s->ds, x, y, c->ch,
> -                          &(c->t_attrib));
> -            c++;
> +    if (s->ds->have_gfx) {
> +        vga_fill_rect(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds),
> +                      color_table[0][COLOR_BLACK]);
> +        y1 = s->y_displayed;
> +        for (y = 0; y < s->height; y++) {
> +            c = s->cells + y1 * s->width;
> +            for (x = 0; x < s->width; x++) {
> +                vga_putcharxy(s->ds, x, y, c->ch,
> +                              &(c->t_attrib));
> +                c++;
> +            }
> +            if (++y1 == s->total_height) {
> +                y1 = 0;
> +            }
>          }
> -        if (++y1 == s->total_height)
> -            y1 = 0;
> +        console_show_cursor(s, 1);
> +        dpy_gfx_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
>      }
> -    console_show_cursor(s, 1);
> -    dpy_update(s->ds, 0, 0, ds_get_width(s->ds), ds_get_height(s->ds));
>  }
>  
>  static void console_scroll(int ydelta)
> @@ -1094,17 +1097,17 @@ void console_select(unsigned int index)
>              qemu_del_timer(active_console->cursor_timer);
>          }
>          active_console = s;
> -        if (ds_get_bits_per_pixel(s->ds)) {
> +        if (ds->have_gfx) {
>              ds->surface = qemu_resize_displaysurface(ds, s->g_width, s->g_height);
> -        } else {
> -            s->ds->surface->width = s->width;
> -            s->ds->surface->height = s->height;
> +            dpy_gfx_resize(ds);
> +        }
> +        if (ds->have_text) {
> +            dpy_text_resize(ds, s->width, s->height);
>          }
>          if (s->cursor_timer) {
>              qemu_mod_timer(s->cursor_timer,
>                     qemu_get_clock_ms(rt_clock) + CONSOLE_CURSOR_PERIOD / 2);
>          }
> -        dpy_resize(s->ds);
>          vga_hw_invalidate();
>      }
>  }
> @@ -1123,10 +1126,10 @@ static int console_puts(CharDriverState *chr, const uint8_t *buf, int len)
>          console_putchar(s, buf[i]);
>      }
>      console_show_cursor(s, 1);
> -    if (ds_get_bits_per_pixel(s->ds) && s->update_x0 < s->update_x1) {
> -        dpy_update(s->ds, s->update_x0, s->update_y0,
> -                   s->update_x1 - s->update_x0,
> -                   s->update_y1 - s->update_y0);
> +    if (s->ds->have_gfx && s->update_x0 < s->update_x1) {
> +        dpy_gfx_update(s->ds, s->update_x0, s->update_y0,
> +                       s->update_x1 - s->update_x0,
> +                       s->update_y1 - s->update_y0);
>      }
>      return len;
>  }
> @@ -1234,8 +1237,8 @@ static void text_console_update(void *opaque, console_ch_t *chardata)
>                                  (s->cells[src].t_attrib.fgcol << 12) |
>                                  (s->cells[src].t_attrib.bgcol << 8) |
>                                  (s->cells[src].t_attrib.bold << 21));
> -        dpy_update(s->ds, s->text_x[0], s->text_y[0],
> -                   s->text_x[1] - s->text_x[0], i - s->text_y[0]);
> +        dpy_text_update(s->ds, s->text_x[0], s->text_y[0],
> +                        s->text_x[1] - s->text_x[0], i - s->text_y[0]);
>          s->text_x[0] = s->width;
>          s->text_y[0] = s->height;
>          s->text_x[1] = 0;
> @@ -1596,7 +1599,7 @@ void qemu_console_resize(DisplayState *ds, int width, int height)
>      s->g_height = height;
>      if (is_graphic_console()) {
>          ds->surface = qemu_resize_displaysurface(ds, width, height);
> -        dpy_resize(ds);
> +        dpy_gfx_resize(ds);
>      }
>  }
>  
> @@ -1604,7 +1607,7 @@ void qemu_console_copy(DisplayState *ds, int src_x, int src_y,
>                         int dst_x, int dst_y, int w, int h)
>  {
>      if (is_graphic_console()) {
> -        dpy_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
> +        dpy_gfx_copy(ds, src_x, src_y, dst_x, dst_y, w, h);
>      }
>  }
>  
> diff --git a/console.h b/console.h
> index fb38ce9..00e2f03 100644
> --- a/console.h
> +++ b/console.h
> @@ -154,15 +154,19 @@ struct DisplayChangeListener {
>      int idle;
>      uint64_t gui_timer_interval;
>  
> -    void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
> -    void (*dpy_resize)(struct DisplayState *s);
> -    void (*dpy_setdata)(struct DisplayState *s);
>      void (*dpy_refresh)(struct DisplayState *s);
> -    void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y,
> -                     int dst_x, int dst_y, int w, int h);
> -    void (*dpy_fill)(struct DisplayState *s, int x, int y,
> -                     int w, int h, uint32_t c);
> +
> +    void (*dpy_gfx_update)(struct DisplayState *s, int x, int y, int w, int h);
> +    void (*dpy_gfx_resize)(struct DisplayState *s);
> +    void (*dpy_gfx_setdata)(struct DisplayState *s);
> +    void (*dpy_gfx_copy)(struct DisplayState *s, int src_x, int src_y,
> +                         int dst_x, int dst_y, int w, int h);
> +    void (*dpy_gfx_fill)(struct DisplayState *s, int x, int y,
> +                         int w, int h, uint32_t c);
> +
>      void (*dpy_text_cursor)(struct DisplayState *s, int x, int y);
> +    void (*dpy_text_resize)(struct DisplayState *s, int w, int h);
> +    void (*dpy_text_update)(struct DisplayState *s, int x, int y, int w, int h);
>  
>      void (*dpy_mouse_set)(struct DisplayState *s, int x, int y, int on);
>      void (*dpy_cursor_define)(struct DisplayState *s, QEMUCursor *cursor);
> @@ -180,6 +184,8 @@ struct DisplayState {
>      struct DisplaySurface *surface;
>      void *opaque;
>      struct QEMUTimer *gui_timer;
> +    bool have_gfx;
> +    bool have_text;
>  
>      struct DisplayAllocator* allocator;
>      QLIST_HEAD(, DisplayChangeListener) listeners;
> @@ -244,28 +250,32 @@ static inline void unregister_displaychangelistener(DisplayState *ds,
>      gui_setup_refresh(ds);
>  }
>  
> -static inline void dpy_update(DisplayState *s, int x, int y, int w, int h)
> +static inline void dpy_gfx_update(DisplayState *s, int x, int y, int w, int h)
>  {
>      struct DisplayChangeListener *dcl;
>      QLIST_FOREACH(dcl, &s->listeners, next) {
> -        dcl->dpy_update(s, x, y, w, h);
> +        if (dcl->dpy_gfx_update) {
> +            dcl->dpy_gfx_update(s, x, y, w, h);
> +        }
>      }
>  }
>  
> -static inline void dpy_resize(DisplayState *s)
> +static inline void dpy_gfx_resize(DisplayState *s)
>  {
>      struct DisplayChangeListener *dcl;
>      QLIST_FOREACH(dcl, &s->listeners, next) {
> -        dcl->dpy_resize(s);
> +        if (dcl->dpy_gfx_resize) {
> +            dcl->dpy_gfx_resize(s);
> +        }
>      }
>  }
>  
> -static inline void dpy_setdata(DisplayState *s)
> +static inline void dpy_gfx_setdata(DisplayState *s)
>  {
>      struct DisplayChangeListener *dcl;
>      QLIST_FOREACH(dcl, &s->listeners, next) {
> -        if (dcl->dpy_setdata) {
> -            dcl->dpy_setdata(s);
> +        if (dcl->dpy_gfx_setdata) {
> +            dcl->dpy_gfx_setdata(s);
>          }
>      }
>  }
> @@ -280,26 +290,26 @@ static inline void dpy_refresh(DisplayState *s)
>      }
>  }
>  
> -static inline void dpy_copy(struct DisplayState *s, int src_x, int src_y,
> +static inline void dpy_gfx_copy(struct DisplayState *s, int src_x, int src_y,
>                               int dst_x, int dst_y, int w, int h)
>  {
>      struct DisplayChangeListener *dcl;
>      QLIST_FOREACH(dcl, &s->listeners, next) {
> -        if (dcl->dpy_copy) {
> -            dcl->dpy_copy(s, src_x, src_y, dst_x, dst_y, w, h);
> +        if (dcl->dpy_gfx_copy) {
> +            dcl->dpy_gfx_copy(s, src_x, src_y, dst_x, dst_y, w, h);
>          } else { /* TODO */
> -            dcl->dpy_update(s, dst_x, dst_y, w, h);
> +            dcl->dpy_gfx_update(s, dst_x, dst_y, w, h);
>          }
>      }
>  }
>  
> -static inline void dpy_fill(struct DisplayState *s, int x, int y,
> -                             int w, int h, uint32_t c)
> +static inline void dpy_gfx_fill(struct DisplayState *s, int x, int y,
> +                                int w, int h, uint32_t c)
>  {
>      struct DisplayChangeListener *dcl;
>      QLIST_FOREACH(dcl, &s->listeners, next) {
> -        if (dcl->dpy_fill) {
> -            dcl->dpy_fill(s, x, y, w, h, c);
> +        if (dcl->dpy_gfx_fill) {
> +            dcl->dpy_gfx_fill(s, x, y, w, h, c);
>          }
>      }
>  }
> @@ -314,6 +324,26 @@ static inline void dpy_text_cursor(struct DisplayState *s, int x, int y)
>      }
>  }
>  
> +static inline void dpy_text_update(DisplayState *s, int x, int y, int w, int h)
> +{
> +    struct DisplayChangeListener *dcl;
> +    QLIST_FOREACH(dcl, &s->listeners, next) {
> +        if (dcl->dpy_text_update) {
> +            dcl->dpy_text_update(s, x, y, w, h);
> +        }
> +    }
> +}
> +
> +static inline void dpy_text_resize(DisplayState *s, int w, int h)
> +{
> +    struct DisplayChangeListener *dcl;
> +    QLIST_FOREACH(dcl, &s->listeners, next) {
> +        if (dcl->dpy_text_resize) {
> +            dcl->dpy_text_resize(s, w, h);
> +        }
> +    }
> +}
> +
>  static inline void dpy_mouse_set(struct DisplayState *s, int x, int y, int on)
>  {
>      struct DisplayChangeListener *dcl;
> diff --git a/hw/blizzard.c b/hw/blizzard.c
> index 06e19b3..1b57eb5 100644
> --- a/hw/blizzard.c
> +++ b/hw/blizzard.c
> @@ -921,8 +921,8 @@ static void blizzard_update_display(void *opaque)
>      for (; y < s->my[1]; y ++, src += bypl, dst += bypl)
>          memcpy(dst, src, bwidth);
>  
> -    dpy_update(s->state, s->mx[0], s->my[0],
> -                    s->mx[1] - s->mx[0], y - s->my[0]);
> +    dpy_gfx_update(s->state, s->mx[0], s->my[0],
> +                   s->mx[1] - s->mx[0], y - s->my[0]);
>  
>      s->mx[0] = s->x;
>      s->mx[1] = 0;
> diff --git a/hw/exynos4210_fimd.c b/hw/exynos4210_fimd.c
> index 7cb2c31..f2443ca 100644
> --- a/hw/exynos4210_fimd.c
> +++ b/hw/exynos4210_fimd.c
> @@ -1307,7 +1307,7 @@ static void exynos4210_fimd_update(void *opaque)
>              fimd_copy_line_toqemu(global_width, s->ifb + global_width * line *
>                      RGBA_SIZE, d + global_width * line * bpp);
>          }
> -        dpy_update(s->console, 0, 0, global_width, global_height);
> +        dpy_gfx_update(s->console, 0, 0, global_width, global_height);
>      }
>      s->invalidate = false;
>      s->vidintcon[1] |= FIMD_VIDINT_INTFRMPEND;
> diff --git a/hw/g364fb.c b/hw/g364fb.c
> index f7b4bf5..8192baf 100644
> --- a/hw/g364fb.c
> +++ b/hw/g364fb.c
> @@ -197,7 +197,8 @@ static void g364fb_draw_graphic8(G364State *s)
>                  reset_dirty(s, page_min, page_max);
>                  page_min = (ram_addr_t)-1;
>                  page_max = 0;
> -                dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
> +                dpy_gfx_update(s->ds, xmin, ymin,
> +                               xmax - xmin + 1, ymax - ymin + 1);
>                  xmin = s->width;
>                  xmax = 0;
>                  ymin = s->height;
> @@ -216,7 +217,7 @@ static void g364fb_draw_graphic8(G364State *s)
>  
>  done:
>      if (page_min != (ram_addr_t)-1) {
> -        dpy_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
> +        dpy_gfx_update(s->ds, xmin, ymin, xmax - xmin + 1, ymax - ymin + 1);
>          reset_dirty(s, page_min, page_max);
>      }
>  }
> @@ -238,7 +239,7 @@ static void g364fb_draw_blank(G364State *s)
>          d += ds_get_linesize(s->ds);
>      }
>  
> -    dpy_update(s->ds, 0, 0, s->width, s->height);
> +    dpy_gfx_update(s->ds, 0, 0, s->width, s->height);
>      s->blanked = 1;
>  }
>  
> diff --git a/hw/jazz_led.c b/hw/jazz_led.c
> index 853bf6d..640e75e 100644
> --- a/hw/jazz_led.c
> +++ b/hw/jazz_led.c
> @@ -196,7 +196,7 @@ static void jazz_led_update_display(void *opaque)
>      }
>  
>      s->state = REDRAW_NONE;
> -    dpy_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
> +    dpy_gfx_update(ds, 0, 0, ds_get_width(ds), ds_get_height(ds));
>  }
>  
>  static void jazz_led_invalidate_display(void *opaque)
> @@ -218,7 +218,7 @@ static void jazz_led_text_update(void *opaque, console_ch_t *chardata)
>      console_write_ch(chardata++, 0x00200100 | buf[0]);
>      console_write_ch(chardata++, 0x00200100 | buf[1]);
>  
> -    dpy_update(s->ds, 0, 0, 2, 1);
> +    dpy_text_update(s->ds, 0, 0, 2, 1);
>  }
>  
>  static int jazz_led_post_load(void *opaque, int version_id)
> diff --git a/hw/milkymist-vgafb.c b/hw/milkymist-vgafb.c
> index 8d36bc1..833881c 100644
> --- a/hw/milkymist-vgafb.c
> +++ b/hw/milkymist-vgafb.c
> @@ -134,7 +134,7 @@ static void vgafb_update_display(void *opaque)
>                                 &first, &last);
>  
>      if (first >= 0) {
> -        dpy_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
> +        dpy_gfx_update(s->ds, 0, first, s->regs[R_HRES], last - first + 1);
>      }
>      s->invalidate = 0;
>  }
> diff --git a/hw/musicpal.c b/hw/musicpal.c
> index beec76b..e0c57c8 100644
> --- a/hw/musicpal.c
> +++ b/hw/musicpal.c
> @@ -526,7 +526,7 @@ static void lcd_refresh(void *opaque)
>                    ds_get_bits_per_pixel(s->ds));
>      }
>  
> -    dpy_update(s->ds, 0, 0, 128*3, 64*3);
> +    dpy_gfx_update(s->ds, 0, 0, 128*3, 64*3);
>  }
>  
>  static void lcd_invalidate(void *opaque)
> diff --git a/hw/nseries.c b/hw/nseries.c
> index 9306aa1..26d5e35 100644
> --- a/hw/nseries.c
> +++ b/hw/nseries.c
> @@ -1376,7 +1376,7 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
>         size until the guest activates the display.  */
>      ds = get_displaystate();
>      ds->surface = qemu_resize_displaysurface(ds, 800, 480);
> -    dpy_resize(ds);
> +    dpy_gfx_resize(ds);
>  }
>  
>  static struct arm_boot_info n800_binfo = {
> diff --git a/hw/omap_lcdc.c b/hw/omap_lcdc.c
> index bf177c2..d7ae303 100644
> --- a/hw/omap_lcdc.c
> +++ b/hw/omap_lcdc.c
> @@ -219,7 +219,7 @@ static void omap_update_display(void *opaque)
>                                 draw_line, omap_lcd->palette,
>                                 &first, &last);
>      if (first >= 0) {
> -        dpy_update(omap_lcd->state, 0, first, width, last - first + 1);
> +        dpy_gfx_update(omap_lcd->state, 0, first, width, last - first + 1);
>      }
>      omap_lcd->invalidate = 0;
>  }
> diff --git a/hw/palm.c b/hw/palm.c
> index d263051..6f6f414 100644
> --- a/hw/palm.c
> +++ b/hw/palm.c
> @@ -273,7 +273,7 @@ static void palmte_init(QEMUMachineInitArgs *args)
>         will set the size once configured, so this just sets an initial
>         size until the guest activates the display.  */
>      ds->surface = qemu_resize_displaysurface(ds, 320, 320);
> -    dpy_resize(ds);
> +    dpy_gfx_resize(ds);
>  }
>  
>  static QEMUMachine palmte_machine = {
> diff --git a/hw/pl110.c b/hw/pl110.c
> index 82486b0..79a3f82 100644
> --- a/hw/pl110.c
> +++ b/hw/pl110.c
> @@ -239,7 +239,7 @@ static void pl110_update_display(void *opaque)
>                                 fn, s->palette,
>                                 &first, &last);
>      if (first >= 0) {
> -        dpy_update(s->ds, 0, first, s->cols, last - first + 1);
> +        dpy_gfx_update(s->ds, 0, first, s->cols, last - first + 1);
>      }
>      s->invalidate = 0;
>  }
> diff --git a/hw/pxa2xx_lcd.c b/hw/pxa2xx_lcd.c
> index 38c3889..b53dfaf 100644
> --- a/hw/pxa2xx_lcd.c
> +++ b/hw/pxa2xx_lcd.c
> @@ -871,20 +871,20 @@ static void pxa2xx_update_display(void *opaque)
>      if (miny >= 0) {
>          switch (s->orientation) {
>          case 0:
> -            dpy_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
> +            dpy_gfx_update(s->ds, 0, miny, s->xres, maxy - miny + 1);
>              break;
>          case 90:
> -            dpy_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
> +            dpy_gfx_update(s->ds, miny, 0, maxy - miny + 1, s->xres);
>              break;
>          case 180:
>              maxy = s->yres - maxy - 1;
>              miny = s->yres - miny - 1;
> -            dpy_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
> +            dpy_gfx_update(s->ds, 0, maxy, s->xres, miny - maxy + 1);
>              break;
>          case 270:
>              maxy = s->yres - maxy - 1;
>              miny = s->yres - miny - 1;
> -            dpy_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
> +            dpy_gfx_update(s->ds, maxy, 0, miny - maxy + 1, s->xres);
>              break;
>          }
>      }
> diff --git a/hw/qxl-render.c b/hw/qxl-render.c
> index e8cf29e..47eb8b4 100644
> --- a/hw/qxl-render.c
> +++ b/hw/qxl-render.c
> @@ -123,17 +123,17 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
>                      qxl->guest_primary.surface.width,
>                      qxl->guest_primary.surface.height);
>          }
> -        dpy_resize(vga->ds);
> +        dpy_gfx_resize(vga->ds);
>      }
>      for (i = 0; i < qxl->num_dirty_rects; i++) {
>          if (qemu_spice_rect_is_empty(qxl->dirty+i)) {
>              break;
>          }
>          qxl_blit(qxl, qxl->dirty+i);
> -        dpy_update(vga->ds,
> -                   qxl->dirty[i].left, qxl->dirty[i].top,
> -                   qxl->dirty[i].right - qxl->dirty[i].left,
> -                   qxl->dirty[i].bottom - qxl->dirty[i].top);
> +        dpy_gfx_update(vga->ds,
> +                       qxl->dirty[i].left, qxl->dirty[i].top,
> +                       qxl->dirty[i].right - qxl->dirty[i].left,
> +                       qxl->dirty[i].bottom - qxl->dirty[i].top);
>      }
>      qxl->num_dirty_rects = 0;
>  }
> diff --git a/hw/qxl.c b/hw/qxl.c
> index d54daf6..1f56fcd 100644
> --- a/hw/qxl.c
> +++ b/hw/qxl.c
> @@ -1864,8 +1864,8 @@ static void display_refresh(struct DisplayState *ds)
>  }
>  
>  static DisplayChangeListener display_listener = {
> -    .dpy_update  = display_update,
> -    .dpy_resize  = display_resize,
> +    .dpy_gfx_update  = display_update,
> +    .dpy_gfx_resize  = display_resize,
>      .dpy_refresh = display_refresh,
>  };
>  
> diff --git a/hw/sm501.c b/hw/sm501.c
> index 4aafe49..50324cd 100644
> --- a/hw/sm501.c
> +++ b/hw/sm501.c
> @@ -1351,7 +1351,7 @@ static void sm501_draw_crt(SM501State * s)
>  	} else {
>  	    if (y_start >= 0) {
>  		/* flush to display */
> -		dpy_update(s->ds, 0, y_start, width, y - y_start);
> +                dpy_gfx_update(s->ds, 0, y_start, width, y - y_start);
>  		y_start = -1;
>  	    }
>  	}
> @@ -1362,7 +1362,7 @@ static void sm501_draw_crt(SM501State * s)
>  
>      /* complete flush to display */
>      if (y_start >= 0)
> -	dpy_update(s->ds, 0, y_start, width, y - y_start);
> +        dpy_gfx_update(s->ds, 0, y_start, width, y - y_start);
>  
>      /* clear dirty flags */
>      if (page_min != ~0l) {
> diff --git a/hw/ssd0303.c b/hw/ssd0303.c
> index 4e1ee6e..d7fd828 100644
> --- a/hw/ssd0303.c
> +++ b/hw/ssd0303.c
> @@ -252,7 +252,7 @@ static void ssd0303_update_display(void *opaque)
>          }
>      }
>      s->redraw = 0;
> -    dpy_update(s->ds, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
> +    dpy_gfx_update(s->ds, 0, 0, 96 * MAGNIFY, 16 * MAGNIFY);
>  }
>  
>  static void ssd0303_invalidate_display(void * opaque)
> diff --git a/hw/ssd0323.c b/hw/ssd0323.c
> index 9c42d64..4098830 100644
> --- a/hw/ssd0323.c
> +++ b/hw/ssd0323.c
> @@ -260,7 +260,7 @@ static void ssd0323_update_display(void *opaque)
>          }
>      }
>      s->redraw = 0;
> -    dpy_update(s->ds, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
> +    dpy_gfx_update(s->ds, 0, 0, 128 * MAGNIFY, 64 * MAGNIFY);
>  }
>  
>  static void ssd0323_invalidate_display(void * opaque)
> diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c
> index 31d4f26..f032027 100644
> --- a/hw/tc6393xb.c
> +++ b/hw/tc6393xb.c
> @@ -454,7 +454,7 @@ static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
>              return;
>      }
>  
> -    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
> +    dpy_gfx_update(s->ds, 0, 0, s->scr_width, s->scr_height);
>  }
>  
>  static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
> @@ -472,7 +472,7 @@ static void tc6393xb_draw_blank(TC6393xbState *s, int full_update)
>          d += ds_get_linesize(s->ds);
>      }
>  
> -    dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height);
> +    dpy_gfx_update(s->ds, 0, 0, s->scr_width, s->scr_height);
>  }
>  
>  static void tc6393xb_update_display(void *opaque)
> diff --git a/hw/tcx.c b/hw/tcx.c
> index 7abe865..7aee2a9 100644
> --- a/hw/tcx.c
> +++ b/hw/tcx.c
> @@ -268,8 +268,8 @@ static void tcx_update_display(void *opaque)
>          } else {
>              if (y_start >= 0) {
>                  /* flush to display */
> -                dpy_update(ts->ds, 0, y_start,
> -                           ts->width, y - y_start);
> +                dpy_gfx_update(ts->ds, 0, y_start,
> +                               ts->width, y - y_start);
>                  y_start = -1;
>              }
>              d += dd * 4;
> @@ -278,8 +278,8 @@ static void tcx_update_display(void *opaque)
>      }
>      if (y_start >= 0) {
>          /* flush to display */
> -        dpy_update(ts->ds, 0, y_start,
> -                   ts->width, y - y_start);
> +        dpy_gfx_update(ts->ds, 0, y_start,
> +                       ts->width, y - y_start);
>      }
>      /* reset modified pages */
>      if (page_max >= page_min) {
> @@ -344,8 +344,8 @@ static void tcx24_update_display(void *opaque)
>          } else {
>              if (y_start >= 0) {
>                  /* flush to display */
> -                dpy_update(ts->ds, 0, y_start,
> -                           ts->width, y - y_start);
> +                dpy_gfx_update(ts->ds, 0, y_start,
> +                               ts->width, y - y_start);
>                  y_start = -1;
>              }
>              d += dd * 4;
> @@ -356,8 +356,8 @@ static void tcx24_update_display(void *opaque)
>      }
>      if (y_start >= 0) {
>          /* flush to display */
> -        dpy_update(ts->ds, 0, y_start,
> -                   ts->width, y - y_start);
> +        dpy_gfx_update(ts->ds, 0, y_start,
> +                       ts->width, y - y_start);
>      }
>      /* reset modified pages */
>      if (page_max >= page_min) {
> diff --git a/hw/vga.c b/hw/vga.c
> index f3256cb..dc8ddde 100644
> --- a/hw/vga.c
> +++ b/hw/vga.c
> @@ -1456,8 +1456,8 @@ static void vga_draw_text(VGACommonState *s, int full_update)
>              ch_attr_ptr++;
>          }
>          if (cx_max != -1) {
> -            dpy_update(s->ds, cx_min * cw, cy * cheight,
> -                       (cx_max - cx_min + 1) * cw, cheight);
> +            dpy_gfx_update(s->ds, cx_min * cw, cy * cheight,
> +                           (cx_max - cx_min + 1) * cw, cheight);
>          }
>          dest += linesize * cheight;
>          line1 = line + cheight;
> @@ -1688,7 +1688,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
>  #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN)
>              s->ds->surface->pf = qemu_different_endianness_pixelformat(depth);
>  #endif
> -            dpy_resize(s->ds);
> +            dpy_gfx_resize(s->ds);
>          } else {
>              qemu_console_resize(s->ds, disp_width, height);
>          }
> @@ -1702,7 +1702,7 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
>      } else if (is_buffer_shared(s->ds->surface) &&
>                 (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {
>          s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);
> -        dpy_setdata(s->ds);
> +        dpy_gfx_setdata(s->ds);
>      }
>  
>      s->rgb_to_pixel =
> @@ -1807,8 +1807,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
>          } else {
>              if (y_start >= 0) {
>                  /* flush to display */
> -                dpy_update(s->ds, 0, y_start,
> -                           disp_width, y - y_start);
> +                dpy_gfx_update(s->ds, 0, y_start,
> +                               disp_width, y - y_start);
>                  y_start = -1;
>              }
>          }
> @@ -1828,8 +1828,8 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
>      }
>      if (y_start >= 0) {
>          /* flush to display */
> -        dpy_update(s->ds, 0, y_start,
> -                   disp_width, y - y_start);
> +        dpy_gfx_update(s->ds, 0, y_start,
> +                       disp_width, y - y_start);
>      }
>      /* reset modified pages */
>      if (page_max >= page_min) {
> @@ -1863,8 +1863,8 @@ static void vga_draw_blank(VGACommonState *s, int full_update)
>          memset(d, val, w);
>          d += ds_get_linesize(s->ds);
>      }
> -    dpy_update(s->ds, 0, 0,
> -               s->last_scr_width, s->last_scr_height);
> +    dpy_gfx_update(s->ds, 0, 0,
> +                   s->last_scr_width, s->last_scr_height);
>  }
>  
>  #define GMODE_TEXT     0
> @@ -2052,9 +2052,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
>              cw != s->last_cw || cheight != s->last_ch) {
>              s->last_scr_width = width * cw;
>              s->last_scr_height = height * cheight;
> -            s->ds->surface->width = width;
> -            s->ds->surface->height = height;
> -            dpy_resize(s->ds);
> +            dpy_text_resize(s->ds, width, height);
>              s->last_width = width;
>              s->last_height = height;
>              s->last_ch = cheight;
> @@ -2087,7 +2085,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
>              for (i = 0; i < size; src ++, dst ++, i ++)
>                  console_write_ch(dst, VMEM2CHTYPE(le32_to_cpu(*src)));
>  
> -            dpy_update(s->ds, 0, 0, width, height);
> +            dpy_text_update(s->ds, 0, 0, width, height);
>          } else {
>              c_max = 0;
>  
> @@ -2110,7 +2108,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
>  
>              if (c_min <= c_max) {
>                  i = TEXTMODE_Y(c_min);
> -                dpy_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
> +                dpy_text_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
>              }
>          }
>  
> @@ -2136,9 +2134,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
>      s->last_width = 60;
>      s->last_height = height = 3;
>      dpy_text_cursor(s->ds, -1, -1);
> -    s->ds->surface->width = s->last_width;
> -    s->ds->surface->height = height;
> -    dpy_resize(s->ds);
> +    dpy_text_resize(s->ds, s->last_width, height);
>  
>      for (dst = chardata, i = 0; i < s->last_width * height; i ++)
>          console_write_ch(dst ++, ' ');
> @@ -2149,7 +2145,7 @@ static void vga_update_text(void *opaque, console_ch_t *chardata)
>      for (i = 0; i < size; i ++)
>          console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
>  
> -    dpy_update(s->ds, 0, 0, s->last_width, height);
> +    dpy_text_update(s->ds, 0, 0, s->last_width, height);
>  }
>  
>  static uint64_t vga_mem_read(void *opaque, hwaddr addr,
> diff --git a/hw/vmware_vga.c b/hw/vmware_vga.c
> index dc92790..34532e5 100644
> --- a/hw/vmware_vga.c
> +++ b/hw/vmware_vga.c
> @@ -321,14 +321,14 @@ static inline void vmsvga_update_rect(struct vmsvga_state_s *s,
>      for (; line > 0; line --, src += bypl, dst += bypl)
>          memcpy(dst, src, width);
>  
> -    dpy_update(s->vga.ds, x, y, w, h);
> +    dpy_gfx_update(s->vga.ds, x, y, w, h);
>  }
>  
>  static inline void vmsvga_update_screen(struct vmsvga_state_s *s)
>  {
>      memcpy(ds_get_data(s->vga.ds), s->vga.vram_ptr,
>             s->bypp * s->width * s->height);
> -    dpy_update(s->vga.ds, 0, 0, s->width, s->height);
> +    dpy_gfx_update(s->vga.ds, 0, 0, s->width, s->height);
>  }
>  
>  static inline void vmsvga_update_rect_delayed(struct vmsvga_state_s *s,
> diff --git a/ui/curses.c b/ui/curses.c
> index c2be2c6..b40b223 100644
> --- a/ui/curses.c
> +++ b/ui/curses.c
> @@ -95,17 +95,16 @@ static void curses_calc_pad(void)
>      }
>  }
>  
> -static void curses_resize(DisplayState *ds)
> +static void curses_resize(DisplayState *ds, int width, int height)
>  {
> -    if (ds_get_width(ds) == gwidth && ds_get_height(ds) == gheight)
> +    if (width == gwidth && height == gheight) {
>          return;
> +    }
>  
> -    gwidth = ds_get_width(ds);
> -    gheight = ds_get_height(ds);
> +    gwidth = width;
> +    gheight = height;
>  
>      curses_calc_pad();
> -    ds->surface->width = width * FONT_WIDTH;
> -    ds->surface->height = height * FONT_HEIGHT;
>  }
>  
>  #ifndef _WIN32
> @@ -167,8 +166,6 @@ static void curses_refresh(DisplayState *ds)
>          clear();
>          refresh();
>          curses_calc_pad();
> -        ds->surface->width = FONT_WIDTH * width;
> -        ds->surface->height = FONT_HEIGHT * height;
>          vga_hw_invalidate();
>          invalidate = 0;
>      }
> @@ -195,8 +192,6 @@ static void curses_refresh(DisplayState *ds)
>              refresh();
>              curses_calc_pad();
>              curses_update(ds, 0, 0, width, height);
> -            ds->surface->width = FONT_WIDTH * width;
> -            ds->surface->height = FONT_HEIGHT * height;
>              continue;
>          }
>  #endif
> @@ -355,13 +350,11 @@ void curses_display_init(DisplayState *ds, int full_screen)
>  #endif
>  
>      dcl = (DisplayChangeListener *) g_malloc0(sizeof(DisplayChangeListener));
> -    dcl->dpy_update = curses_update;
> -    dcl->dpy_resize = curses_resize;
> +    dcl->dpy_text_update = curses_update;
> +    dcl->dpy_text_resize = curses_resize;
>      dcl->dpy_refresh = curses_refresh;
>      dcl->dpy_text_cursor = curses_cursor_position;
>      register_displaychangelistener(ds, dcl);
> -    qemu_free_displaysurface(ds);
> -    ds->surface = qemu_create_displaysurface_from(640, 400, 0, 0, (uint8_t*) screen);
>  
>      invalidate = 1;
>  }
> diff --git a/ui/sdl.c b/ui/sdl.c
> index f8ead93..fac1a47 100644
> --- a/ui/sdl.c
> +++ b/ui/sdl.c
> @@ -553,7 +553,7 @@ static void sdl_scale(DisplayState *ds, int width, int height)
>      if (!is_buffer_shared(ds->surface)) {
>          ds->surface = qemu_resize_displaysurface(ds, ds_get_width(ds),
>                                                   ds_get_height(ds));
> -        dpy_resize(ds);
> +        dpy_gfx_resize(ds);
>      }
>  }
>  
> @@ -1020,11 +1020,11 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
>      }
>  
>      dcl = g_malloc0(sizeof(DisplayChangeListener));
> -    dcl->dpy_update = sdl_update;
> -    dcl->dpy_resize = sdl_resize;
> +    dcl->dpy_gfx_update = sdl_update;
> +    dcl->dpy_gfx_resize = sdl_resize;
>      dcl->dpy_refresh = sdl_refresh;
> -    dcl->dpy_setdata = sdl_setdata;
> -    dcl->dpy_fill = sdl_fill;
> +    dcl->dpy_gfx_setdata = sdl_setdata;
> +    dcl->dpy_gfx_fill = sdl_fill;
>      dcl->dpy_mouse_set = sdl_mouse_warp;
>      dcl->dpy_cursor_define = sdl_mouse_define;
>      register_displaychangelistener(ds, dcl);
> @@ -1034,7 +1034,7 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
>      da->resize_displaysurface = sdl_resize_displaysurface;
>      da->free_displaysurface = sdl_free_displaysurface;
>      if (register_displayallocator(ds, da) == da) {
> -        dpy_resize(ds);
> +        dpy_gfx_resize(ds);
>      }
>  
>      mouse_mode_notifier.notify = sdl_mouse_mode_change;
> diff --git a/ui/spice-display.c b/ui/spice-display.c
> index 5779fa8..fb99148 100644
> --- a/ui/spice-display.c
> +++ b/ui/spice-display.c
> @@ -571,8 +571,8 @@ static void display_refresh(struct DisplayState *ds)
>  }
>  
>  static DisplayChangeListener display_listener = {
> -    .dpy_update  = display_update,
> -    .dpy_resize  = display_resize,
> +    .dpy_gfx_update  = display_update,
> +    .dpy_gfx_resize  = display_resize,
>      .dpy_refresh = display_refresh,
>  };
>  
> diff --git a/ui/vnc.c b/ui/vnc.c
> index 1b70db7..0ae1c74 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -2753,10 +2753,10 @@ void vnc_display_init(DisplayState *ds)
>      qemu_mutex_init(&vs->mutex);
>      vnc_start_worker_thread();
>  
> -    dcl->dpy_copy = vnc_dpy_copy;
> -    dcl->dpy_update = vnc_dpy_update;
> -    dcl->dpy_resize = vnc_dpy_resize;
> -    dcl->dpy_setdata = vnc_dpy_setdata;
> +    dcl->dpy_gfx_copy = vnc_dpy_copy;
> +    dcl->dpy_gfx_update = vnc_dpy_update;
> +    dcl->dpy_gfx_resize = vnc_dpy_resize;
> +    dcl->dpy_gfx_setdata = vnc_dpy_setdata;
>      dcl->dpy_mouse_set = vnc_mouse_set;
>      dcl->dpy_cursor_define = vnc_dpy_cursor_define;
>      register_displaychangelistener(ds, dcl);
> diff --git a/vl.c b/vl.c
> index 4c45b02..8716fc0 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1375,11 +1375,18 @@ 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->dpy_refresh != NULL) {
>              need_timer = true;
> -            break;
> +        }
> +        if (dcl->dpy_gfx_update != NULL) {
> +            have_gfx = true;
> +        }
> +        if (dcl->dpy_text_update != NULL) {
> +            have_text = true;
>          }
>      }
>  
> @@ -1392,6 +1399,9 @@ void gui_setup_refresh(DisplayState *ds)
>          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 {
> @@ -3866,7 +3876,7 @@ int main(int argc, char **argv, char **envp)
>  #endif
>  
>      /* display setup */
> -    dpy_resize(ds);
> +    dpy_gfx_resize(ds);
>      text_consoles_set_display(ds);
>  
>      if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
> 



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 259 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PATCH 05/22] console: untangle gfx & txt updates
  2012-11-02  7:20   ` Jan Kiszka
@ 2012-11-02 14:44     ` Peter Maydell
  0 siblings, 0 replies; 29+ messages in thread
From: Peter Maydell @ 2012-11-02 14:44 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Gerd Hoffmann, qemu-devel

On 2 November 2012 08:20, Jan Kiszka <jan.kiszka@web.de> wrote:
> On 2012-11-01 14:04, Gerd Hoffmann wrote:
>> Stop abusing displaysurface fields for text mode displays.
>> (bpp = 0, width = cols, height = lines).
>>
>> Add flags to displaystate indicating whenever text mode display
>> (curses) or gfx mode displays (sdl, vnc, ...) are present.
>>
>> Add separate displaychangelistener callbacks for text / gfx mode
>> resize & updates.
>>
>> This allows to enable gfx and txt diplays at the same time and also
>> paves the way for more cleanups in the future.
>
> Breaks building xenfb.c.

Also breaks building the Cocoa frontend on MacOS:

  OBJC  ui/cocoa.o
ui/cocoa.m:771:10: warning:
      'beginSheetForDirectory:file:types:modalForWindow:modalDelegate:didEndSelector:contextInfo:'
is
      deprecated [-Wdeprecated-declarations]
        [op beginSheetForDirectory:nil file:nil types:[NSArray ...
         ^
ui/cocoa.m:810:32: warning: 'filename' is deprecated [-Wdeprecated-declarations]
        char *img = (char*)[ [ sheet filename ]
cStringUsingEncoding:NSASCIIStringEncoding];
                               ^
ui/cocoa.m:1020:10: error: no member named 'dpy_update' in 'struct
DisplayChangeListener'
    dcl->dpy_update = cocoa_update;
    ~~~  ^
ui/cocoa.m:1021:10: error: no member named 'dpy_resize' in 'struct
DisplayChangeListener'
    dcl->dpy_resize = cocoa_resize;
    ~~~  ^
2 warnings and 2 errors generated.
make: *** [ui/cocoa.o] Error 1

'git grep dpy_update' suggests that xenfb and cocoa are the only two
breakages though.


-- PMM

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering
  2012-11-01 19:33 ` [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Anthony Liguori
@ 2012-11-02 16:14   ` Andreas Färber
  2012-11-02 16:32     ` Andreas Färber
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Färber @ 2012-11-02 16:14 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel, Anthony Liguori, Alexander Graf

Am 01.11.2012 20:33, schrieb Anthony Liguori:
> Gerd Hoffmann <kraxel@redhat.com> writes:
> 
>>   Hi,
>>
>> Sitting on these too long already.  Series has been on the list a while
>> back, only splitted into two parts (separate "console cleanups" series
>> carrying patches 1-8).  Patch 11 was updated according to Paolos
>> suggestion, otherwise the patches are unmodified.
>>
>> please pull,
>>   Gerd
> 
> Pulled. Thanks.

Getting this on SLES 11 SP2 s390x (pixman 0.16.0):

cc1: warnings being treated as errors
In file included from /home/andreas/qemu-s390/qemu-pixman.h:4,
                 from /home/andreas/qemu-s390/console.h:5,
                 from /home/andreas/qemu-s390/qemu-timer.c:28:
/usr/include/pixman-1/pixman.h:225: error: redundant redeclaration of
‘pixman_transform_from_pixman_f_transform’
/usr/include/pixman-1/pixman.h:221: error: previous declaration of
‘pixman_transform_from_pixman_f_transform’ was here
make: *** [qemu-timer.o] Fehler 1
make: *** Warte auf noch nicht beendete Prozesse...

Any idea how to resolve?

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering
  2012-11-02 16:14   ` Andreas Färber
@ 2012-11-02 16:32     ` Andreas Färber
  2012-11-03 12:33       ` Blue Swirl
  0 siblings, 1 reply; 29+ messages in thread
From: Andreas Färber @ 2012-11-02 16:32 UTC (permalink / raw)
  To: Gerd Hoffmann, Alexander Graf; +Cc: qemu-devel, Anthony Liguori

Am 02.11.2012 17:14, schrieb Andreas Färber:
> Am 01.11.2012 20:33, schrieb Anthony Liguori:
>> Gerd Hoffmann <kraxel@redhat.com> writes:
>>
>>>   Hi,
>>>
>>> Sitting on these too long already.  Series has been on the list a while
>>> back, only splitted into two parts (separate "console cleanups" series
>>> carrying patches 1-8).  Patch 11 was updated according to Paolos
>>> suggestion, otherwise the patches are unmodified.
>>>
>>> please pull,
>>>   Gerd
>>
>> Pulled. Thanks.
> 
> Getting this on SLES 11 SP2 s390x (pixman 0.16.0):
> 
> cc1: warnings being treated as errors
> In file included from /home/andreas/qemu-s390/qemu-pixman.h:4,
>                  from /home/andreas/qemu-s390/console.h:5,
>                  from /home/andreas/qemu-s390/qemu-timer.c:28:
> /usr/include/pixman-1/pixman.h:225: error: redundant redeclaration of
> ‘pixman_transform_from_pixman_f_transform’
> /usr/include/pixman-1/pixman.h:221: error: previous declaration of
> ‘pixman_transform_from_pixman_f_transform’ was here
> make: *** [qemu-timer.o] Fehler 1
> make: *** Warte auf noch nicht beendete Prozesse...
> 
> Any idea how to resolve?

So, it seems that our pixman 0.16.0 header has a genuine redundant
declaration, not influenced by qemu-pixman.h. I worked around it by
manually changing -Wredundant-decl to -Wno-redundant-decl in configure,
similar to what some FreeBSD versions needed. Suggestions for a real
warnings-fix or configure-detection of incompatible headers appreciated!

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering
  2012-11-02 16:32     ` Andreas Färber
@ 2012-11-03 12:33       ` Blue Swirl
  0 siblings, 0 replies; 29+ messages in thread
From: Blue Swirl @ 2012-11-03 12:33 UTC (permalink / raw)
  To: Andreas Färber
  Cc: qemu-devel, Gerd Hoffmann, Anthony Liguori, Alexander Graf

On Fri, Nov 2, 2012 at 4:32 PM, Andreas Färber <afaerber@suse.de> wrote:
> Am 02.11.2012 17:14, schrieb Andreas Färber:
>> Am 01.11.2012 20:33, schrieb Anthony Liguori:
>>> Gerd Hoffmann <kraxel@redhat.com> writes:
>>>
>>>>   Hi,
>>>>
>>>> Sitting on these too long already.  Series has been on the list a while
>>>> back, only splitted into two parts (separate "console cleanups" series
>>>> carrying patches 1-8).  Patch 11 was updated according to Paolos
>>>> suggestion, otherwise the patches are unmodified.
>>>>
>>>> please pull,
>>>>   Gerd
>>>
>>> Pulled. Thanks.
>>
>> Getting this on SLES 11 SP2 s390x (pixman 0.16.0):
>>
>> cc1: warnings being treated as errors
>> In file included from /home/andreas/qemu-s390/qemu-pixman.h:4,
>>                  from /home/andreas/qemu-s390/console.h:5,
>>                  from /home/andreas/qemu-s390/qemu-timer.c:28:
>> /usr/include/pixman-1/pixman.h:225: error: redundant redeclaration of
>> ‘pixman_transform_from_pixman_f_transform’
>> /usr/include/pixman-1/pixman.h:221: error: previous declaration of
>> ‘pixman_transform_from_pixman_f_transform’ was here
>> make: *** [qemu-timer.o] Fehler 1
>> make: *** Warte auf noch nicht beendete Prozesse...
>>
>> Any idea how to resolve?
>
> So, it seems that our pixman 0.16.0 header has a genuine redundant
> declaration, not influenced by qemu-pixman.h. I worked around it by
> manually changing -Wredundant-decl to -Wno-redundant-decl in configure,
> similar to what some FreeBSD versions needed. Suggestions for a real
> warnings-fix or configure-detection of incompatible headers appreciated!

Maybe adding
#pragma GCC diagnostic ignored "-Wredundant-decl"
#pragma GCC diagnostic error "-Wredundant-decl"

to qemu-pixman.h.

I still have another problem, out of tree build with submodule version
does not work (mingw). With this change it almost works, but ranlib is
not propagated and tests (if not disabled) fail.
diff --git a/Makefile b/Makefile
index ca14a21..15a3080 100644
--- a/Makefile
+++ b/Makefile
@@ -122,7 +122,7 @@ subdir-pixman: pixman/Makefile
        $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C pixman
V="$(V)" all,)

 pixman/Makefile: $(SRC_PATH)/pixman/configure
-       (cd pixman; $(SRC_PATH)/pixman/configure --disable-shared
--enable-static)
+       (cd pixman; CC=$(CC) LD=$(LD) AR=$(AR) NM=$(NM)
RANLIB=$(RANLIB) $(SRC_PATH)/pixman/configure --disable-shared
--enable-static)

 $(SRC_PATH)/pixman/configure:
        (cd $(SRC_PATH)/pixman; autoreconf -v --install)
diff --git a/configure b/configure
index 8e70cbb..15cfc08 100755
--- a/configure
+++ b/configure
@@ -252,9 +252,11 @@ done

 cc="${CC-${cross_prefix}gcc}"
 ar="${AR-${cross_prefix}ar}"
+nm="${NM-${cross_prefix}nm}"
 objcopy="${OBJCOPY-${cross_prefix}objcopy}"
 ld="${LD-${cross_prefix}ld}"
 libtool="${LIBTOOL-${cross_prefix}libtool}"
+ranlib="${RANLIB-${cross_prefix}ranlib}"
 strip="${STRIP-${cross_prefix}strip}"
 windres="${WINDRES-${cross_prefix}windres}"
 pkg_config_exe="${PKG_CONFIG-${cross_prefix}pkg-config}"
@@ -2121,8 +2123,8 @@ else
     echo "      git submodule update --init pixman"
     exit 1
   fi
-  pixman_cflags="-I${source_path}/pixman/pixman"
-  pixman_libs="-Lpixman/pixman/.libs -lpixman-1"
+  pixman_cflags="-I\$(SRC_PATH)/pixman/pixman -I\$(BUILD_DIR)/pixman/pixman"
+  pixman_libs="-L\$(BUILD_DIR)/pixman/pixman/.libs -lpixman-1"
 fi
 QEMU_CFLAGS="$QEMU_CFLAGS $pixman_cflags"
 libs_softmmu="$libs_softmmu $pixman_libs"
@@ -3634,8 +3636,10 @@ echo "CC_I386=$cc_i386" >> $config_host_mak
 echo "HOST_CC=$host_cc" >> $config_host_mak
 echo "OBJCC=$objcc" >> $config_host_mak
 echo "AR=$ar" >> $config_host_mak
+echo "NM=$nm" >> $config_host_mak
 echo "OBJCOPY=$objcopy" >> $config_host_mak
 echo "LD=$ld" >> $config_host_mak
+echo "RANLIB=$RANLIB" >> $config_host_mak
 echo "WINDRES=$windres" >> $config_host_mak
 echo "LIBTOOL=$libtool" >> $config_host_mak
 echo "CFLAGS=$CFLAGS" >> $config_host_mak

Hacked pixman/Makefile.in:
--- pixman/Makefile.in~ 2012-11-03 07:41:28.000000000 +0000
+++ pixman/Makefile.in  2012-11-03 12:27:05.000000000 +0000
@@ -269,7 +269,7 @@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-SUBDIRS = pixman test
+SUBDIRS = pixman
 pkgconfigdir = $(libdir)/pkgconfig
 pkgconfig_DATA = pixman-1.pc
 GPGKEY = 6FF7C1A8

  CCLD   clip-test.exe
i586-mingw32msvc-gcc: unrecognized option '-pthread'
i586-mingw32msvc-gcc: unrecognized option '-pthread'
/usr/lib/gcc/i586-mingw32msvc/4.4.4/../../../../i586-mingw32msvc/bin/ld:
cannot find -lgtk-x11-2.0

>
> Andreas
>
> --
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg
>

^ permalink raw reply related	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2012-11-03 12:33 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-01 13:03 [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Gerd Hoffmann
2012-11-01 13:03 ` [Qemu-devel] [PATCH 01/22] console: QLIST-ify display change listeners Gerd Hoffmann
2012-11-01 13:03 ` [Qemu-devel] [PATCH 02/22] console: add unregister_displaychangelistener Gerd Hoffmann
2012-11-01 13:03 ` [Qemu-devel] [PATCH 03/22] console: move set_mouse + cursor_define callbacks Gerd Hoffmann
2012-11-01 13:03 ` [Qemu-devel] [PATCH 04/22] console: s/TextConsole/QemuConsole/ Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 05/22] console: untangle gfx & txt updates Gerd Hoffmann
2012-11-02  7:20   ` Jan Kiszka
2012-11-02 14:44     ` Peter Maydell
2012-11-01 13:04 ` [Qemu-devel] [PATCH 06/22] console: init displaychangelisteners on register Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 07/22] vga: fix text mode updating Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 08/22] console: remove dpy_gfx_fill Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 09/22] console: remove DisplayAllocator Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 10/22] pixman: add submodule Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 11/22] pixman: windup in configure & makefiles Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 12/22] pixman: helper functions Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 13/22] pixman: add pixman image to DisplaySurface Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 14/22] console: make qemu_alloc_display static Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 15/22] console: don't set PixelFormat alpha fields for 32bpp Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 16/22] qxl: stop direct access to DisplaySurface fields Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 17/22] vga: " Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 18/22] pixman: switch screendump function Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 19/22] pixman/vnc: use pixman images in vnc Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 20/22] pixman/vnc: remove rgb_prepare_row* functions Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 21/22] pixman/vnc: remove dead code Gerd Hoffmann
2012-11-01 13:04 ` [Qemu-devel] [PATCH 22/22] pixman: drop obsolete fields from DisplaySurface Gerd Hoffmann
2012-11-01 19:33 ` [Qemu-devel] [PULL 00/22] console cleanups & pixman rendering Anthony Liguori
2012-11-02 16:14   ` Andreas Färber
2012-11-02 16:32     ` Andreas Färber
2012-11-03 12:33       ` Blue Swirl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).