All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/14] pixman patch series.
@ 2012-10-17 13:29 Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 01/14] console: remove DisplayAllocator Gerd Hoffmann
                   ` (13 more replies)
  0 siblings, 14 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

First round of pixman patches for qemu, so we have something concrete to
discuss.  Applies on top of the "console cleanups" patch series posted a
few days ago.

The long-term goal is to stop reinventing the wheel over and over when
it comes to pixel manipulation and to use pixman instead.  This patch
series is a start.  It switches a central data structure
(DisplaySurface) over to pixman, so the ui code can easily use pixman
to manipulate pixel data.  It also collects some low-hanging fruit to
show pixman in action.

Comments?

cheers,
  Gerd

Gerd Hoffmann (14):
  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                     |  107 +++++++---------
 console.h                     |   62 ++++------
 hw/qxl-render.c               |    2 +-
 hw/vga.c                      |   48 +++-----
 pixman                        |    1 +
 qemu-common.h                 |    1 -
 qemu-pixman.c                 |   60 +++++++++
 qemu-pixman.h                 |   32 +++++
 ui/sdl.c                      |  117 +----------------
 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                      |  239 ++++++++++++++++++-----------------
 ui/vnc.h                      |   19 +++-
 20 files changed, 508 insertions(+), 608 deletions(-)
 create mode 160000 pixman
 create mode 100644 qemu-pixman.c
 create mode 100644 qemu-pixman.h

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

* [Qemu-devel] [PATCH 01/14] console: remove DisplayAllocator
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 02/14] pixman: add submodule Gerd Hoffmann
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 78e842f..8f13668 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] 22+ messages in thread

* [Qemu-devel] [PATCH 02/14] pixman: add submodule
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 01/14] console: remove DisplayAllocator Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles Gerd Hoffmann
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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] 22+ messages in thread

* [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 01/14] console: remove DisplayAllocator Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 02/14] pixman: add submodule Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 14:26   ` Paolo Bonzini
  2012-11-22 12:34   ` Stefano Stabellini
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 04/14] pixman: helper functions Gerd Hoffmann
                   ` (10 subsequent siblings)
  13 siblings, 2 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 a9c22bf..5699101 100644
--- a/Makefile
+++ b/Makefile
@@ -105,6 +105,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 353d788..4b916aa 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.
   ;;
+  --pixman-system) pixman="system"
+  ;;
+  --pixman-internal) pixman="internal"
+  ;;
   --disable-sdl) sdl="no"
   ;;
   --enable-sdl) sdl="yes"
@@ -2117,6 +2122,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
@@ -3147,6 +3180,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"
@@ -3909,6 +3943,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
@@ -4112,6 +4149,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] 22+ messages in thread

* [Qemu-devel] [PATCH 04/14] pixman: helper functions
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 05/14] pixman: add pixman image to DisplaySurface Gerd Hoffmann
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 74b3542..73dd3bc 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -64,6 +64,7 @@ common-obj-y = $(block-obj-y) blockdev.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] 22+ messages in thread

* [Qemu-devel] [PATCH 05/14] pixman: add pixman image to DisplaySurface
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 04/14] pixman: helper functions Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 06/14] console: make qemu_alloc_display static Gerd Hoffmann
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 8f13668..c546e98 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] 22+ messages in thread

* [Qemu-devel] [PATCH 06/14] console: make qemu_alloc_display static
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 05/14] pixman: add pixman image to DisplaySurface Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 07/14] console: don't set PixelFormat alpha fields for 32bpp Gerd Hoffmann
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 c546e98..96ef165 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] 22+ messages in thread

* [Qemu-devel] [PATCH 07/14] console: don't set PixelFormat alpha fields for 32bpp
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 06/14] console: make qemu_alloc_display static Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-19 17:02   ` Stefano Stabellini
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 08/14] qxl: stop direct access to DisplaySurface fields Gerd Hoffmann
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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] 22+ messages in thread

* [Qemu-devel] [PATCH 08/14] qxl: stop direct access to DisplaySurface fields.
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 07/14] console: don't set PixelFormat alpha fields for 32bpp Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 09/14] vga: " Gerd Hoffmann
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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] 22+ messages in thread

* [Qemu-devel] [PATCH 09/14] vga: stop direct access to DisplaySurface fields.
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 08/14] qxl: stop direct access to DisplaySurface fields Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 10/14] pixman: switch screendump function Gerd Hoffmann
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 a0ba94d..4d34469 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -1718,8 +1718,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] 22+ messages in thread

* [Qemu-devel] [PATCH 10/14] pixman: switch screendump function.
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 09/14] vga: " Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 11/14] pixman/vnc: use pixman images in vnc Gerd Hoffmann
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 4d34469..4ffd57c 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -2417,13 +2417,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");
@@ -2432,33 +2431,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;
@@ -2466,7 +2449,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] 22+ messages in thread

* [Qemu-devel] [PATCH 11/14] pixman/vnc: use pixman images in vnc.
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 10/14] pixman: switch screendump function Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-19 18:04   ` Stefano Stabellini
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 12/14] pixman/vnc: remove rgb_prepare_row* functions Gerd Hoffmann
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 087b84d..c55a5f0 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 a192e61..0cf164a 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;
@@ -1859,9 +1874,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 {
@@ -1881,23 +1896,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);
 
@@ -1908,8 +1922,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 */
@@ -1917,27 +1933,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));
 }
 
@@ -2441,12 +2455,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;
@@ -2460,8 +2476,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;
@@ -2530,12 +2546,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 };
 
@@ -2549,22 +2568,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;
@@ -2579,9 +2607,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] 22+ messages in thread

* [Qemu-devel] [PATCH 12/14] pixman/vnc: remove rgb_prepare_row* functions
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 11/14] pixman/vnc: use pixman images in vnc Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 13/14] pixman/vnc: remove dead code Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 14/14] pixman: drop obsolete fields from DisplaySurface Gerd Hoffmann
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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] 22+ messages in thread

* [Qemu-devel] [PATCH 13/14] pixman/vnc: remove dead code.
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 12/14] pixman/vnc: remove rgb_prepare_row* functions Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 14/14] pixman: drop obsolete fields from DisplaySurface Gerd Hoffmann
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 0cf164a..869ad46 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] 22+ messages in thread

* [Qemu-devel] [PATCH 14/14] pixman: drop obsolete fields from DisplaySurface
  2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
                   ` (12 preceding siblings ...)
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 13/14] pixman/vnc: remove dead code Gerd Hoffmann
@ 2012-10-17 13:29 ` Gerd Hoffmann
  13 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-17 13:29 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 96ef165..f66fbfc 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] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles Gerd Hoffmann
@ 2012-10-17 14:26   ` Paolo Bonzini
  2012-11-22 12:34   ` Stefano Stabellini
  1 sibling, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2012-10-17 14:26 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

Il 17/10/2012 15:29, Gerd Hoffmann ha scritto:
> 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 a9c22bf..5699101 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -105,6 +105,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 353d788..4b916aa 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.
>    ;;
> +  --pixman-system) pixman="system"
> +  ;;
> +  --pixman-internal) pixman="internal"
> +  ;;

Let's make this more autoconfy:
--with-system-pixman/--without-system-pixman.

Paolo

>    --disable-sdl) sdl="no"
>    ;;
>    --enable-sdl) sdl="yes"
> @@ -2117,6 +2122,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
> @@ -3147,6 +3180,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"
> @@ -3909,6 +3943,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
> @@ -4112,6 +4149,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"
> 

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

* Re: [Qemu-devel] [PATCH 07/14] console: don't set PixelFormat alpha fields for 32bpp
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 07/14] console: don't set PixelFormat alpha fields for 32bpp Gerd Hoffmann
@ 2012-10-19 17:02   ` Stefano Stabellini
  2012-10-22  5:26     ` Gerd Hoffmann
  0 siblings, 1 reply; 22+ messages in thread
From: Stefano Stabellini @ 2012-10-19 17:02 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Wed, 17 Oct 2012, Gerd Hoffmann wrote:
> 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>

Actually the alpha mask was left to 0 on purpose to ignore it.
At the same time we set amax, ashift and abits to signal the presence of
an alpha byte in the pixel format.


>  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	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 11/14] pixman/vnc: use pixman images in vnc.
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 11/14] pixman/vnc: use pixman images in vnc Gerd Hoffmann
@ 2012-10-19 18:04   ` Stefano Stabellini
  2012-10-22  5:40     ` Gerd Hoffmann
  0 siblings, 1 reply; 22+ messages in thread
From: Stefano Stabellini @ 2012-10-19 18:04 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Wed, 17 Oct 2012, Gerd Hoffmann wrote:
> 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.

Is this really a good idea?
It is very common for a vnc client to ask for 16 or 8 bpp on slow
connections.

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

* Re: [Qemu-devel] [PATCH 07/14] console: don't set PixelFormat alpha fields for 32bpp
  2012-10-19 17:02   ` Stefano Stabellini
@ 2012-10-22  5:26     ` Gerd Hoffmann
  0 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-22  5:26 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: qemu-devel

On 10/19/12 19:02, Stefano Stabellini wrote:
> On Wed, 17 Oct 2012, Gerd Hoffmann wrote:
>> 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>
> 
> Actually the alpha mask was left to 0 on purpose to ignore it.
> At the same time we set amax, ashift and abits to signal the presence of
> an alpha byte in the pixel format.

Hmm?  I still don't see t he point of the current mix.  Either the byte
is alpha or it is unused ...

cheers,
  Gerd

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

* Re: [Qemu-devel] [PATCH 11/14] pixman/vnc: use pixman images in vnc.
  2012-10-19 18:04   ` Stefano Stabellini
@ 2012-10-22  5:40     ` Gerd Hoffmann
  0 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-10-22  5:40 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: qemu-devel

On 10/19/12 20:04, Stefano Stabellini wrote:
> On Wed, 17 Oct 2012, Gerd Hoffmann wrote:
>> 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.
> 
> Is this really a good idea?
> It is very common for a vnc client to ask for 16 or 8 bpp on slow
> connections.

The 16bpp modes (guest video modes) are slowly dying, so I think it is
best to operate at 32bpp internally.  First because we don't need to
convert when reading the guest framebuffer.  Second the format is easy
to deal with.

When sending out the data to the client we might have to convert, but
that isn't new.

cheers,
  Gerd

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

* Re: [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles
  2012-10-17 13:29 ` [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles Gerd Hoffmann
  2012-10-17 14:26   ` Paolo Bonzini
@ 2012-11-22 12:34   ` Stefano Stabellini
  2012-11-22 12:59     ` Gerd Hoffmann
  1 sibling, 1 reply; 22+ messages in thread
From: Stefano Stabellini @ 2012-11-22 12:34 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

I have just noticed that we haven't actually written anywhere what's the
oldest version of pixman we support.

Do you know which one it is?


On Wed, 17 Oct 2012, Gerd Hoffmann wrote:
> 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 a9c22bf..5699101 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -105,6 +105,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 353d788..4b916aa 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.
>    ;;
> +  --pixman-system) pixman="system"
> +  ;;
> +  --pixman-internal) pixman="internal"
> +  ;;
>    --disable-sdl) sdl="no"
>    ;;
>    --enable-sdl) sdl="yes"
> @@ -2117,6 +2122,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
> @@ -3147,6 +3180,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"
> @@ -3909,6 +3943,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
> @@ -4112,6 +4149,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	[flat|nested] 22+ messages in thread

* Re: [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles
  2012-11-22 12:34   ` Stefano Stabellini
@ 2012-11-22 12:59     ` Gerd Hoffmann
  0 siblings, 0 replies; 22+ messages in thread
From: Gerd Hoffmann @ 2012-11-22 12:59 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: qemu-devel

On 11/22/12 13:34, Stefano Stabellini wrote:
> I have just noticed that we haven't actually written anywhere what's the
> oldest version of pixman we support.
> 
> Do you know which one it is?

0.18.4 is known good.

cheers,
  Gerd

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

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

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-17 13:29 [Qemu-devel] [PATCH 00/14] pixman patch series Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 01/14] console: remove DisplayAllocator Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 02/14] pixman: add submodule Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 03/14] pixman: windup in configure & makefiles Gerd Hoffmann
2012-10-17 14:26   ` Paolo Bonzini
2012-11-22 12:34   ` Stefano Stabellini
2012-11-22 12:59     ` Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 04/14] pixman: helper functions Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 05/14] pixman: add pixman image to DisplaySurface Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 06/14] console: make qemu_alloc_display static Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 07/14] console: don't set PixelFormat alpha fields for 32bpp Gerd Hoffmann
2012-10-19 17:02   ` Stefano Stabellini
2012-10-22  5:26     ` Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 08/14] qxl: stop direct access to DisplaySurface fields Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 09/14] vga: " Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 10/14] pixman: switch screendump function Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 11/14] pixman/vnc: use pixman images in vnc Gerd Hoffmann
2012-10-19 18:04   ` Stefano Stabellini
2012-10-22  5:40     ` Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 12/14] pixman/vnc: remove rgb_prepare_row* functions Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 13/14] pixman/vnc: remove dead code Gerd Hoffmann
2012-10-17 13:29 ` [Qemu-devel] [PATCH 14/14] pixman: drop obsolete fields from DisplaySurface Gerd Hoffmann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.