summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--hw/display/qxl-render.c7
-rw-r--r--hw/display/vga.c12
-rw-r--r--hw/display/vmware_vga.c6
-rw-r--r--hw/display/xenfb.c8
-rw-r--r--include/ui/console.h25
-rw-r--r--include/ui/qemu-pixman.h4
-rw-r--r--trace-events2
-rw-r--r--ui/console.c253
-rw-r--r--ui/qemu-pixman.c90
-rw-r--r--ui/sdl.c5
-rw-r--r--ui/vnc-enc-tight.c12
11 files changed, 250 insertions, 174 deletions
diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index bcc5c3701a..e812ddd6e7 100644
--- a/hw/display/qxl-render.c
+++ b/hw/display/qxl-render.c
@@ -116,13 +116,14 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
                qxl->guest_primary.bytes_pp,
                qxl->guest_primary.bits_pp);
         if (qxl->guest_primary.qxl_stride > 0) {
+            pixman_format_code_t format =
+                qemu_default_pixman_format(qxl->guest_primary.bits_pp, true);
             surface = qemu_create_displaysurface_from
                 (qxl->guest_primary.surface.width,
                  qxl->guest_primary.surface.height,
-                 qxl->guest_primary.bits_pp,
+                 format,
                  qxl->guest_primary.abs_stride,
-                 qxl->guest_primary.data,
-                 false);
+                 qxl->guest_primary.data);
         } else {
             surface = qemu_create_displaysurface
                 (qxl->guest_primary.surface.width,
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 62e6243c6f..f24b48ba95 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1725,9 +1725,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         height != s->last_height ||
         s->last_depth != depth) {
         if (depth == 32 || (depth == 16 && !byteswap)) {
+            pixman_format_code_t format =
+                qemu_default_pixman_format(depth, !byteswap);
             surface = qemu_create_displaysurface_from(disp_width,
-                    height, depth, s->line_offset,
-                    s->vram_ptr + (s->start_addr * 4), byteswap);
+                    height, format, s->line_offset,
+                    s->vram_ptr + (s->start_addr * 4));
             dpy_gfx_replace_surface(s->con, surface);
         } else {
             qemu_console_resize(s->con, disp_width, height);
@@ -1743,9 +1745,11 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
     } else if (is_buffer_shared(surface) &&
                (full_update || surface_data(surface) != s->vram_ptr
                 + (s->start_addr * 4))) {
+        pixman_format_code_t format =
+            qemu_default_pixman_format(depth, !byteswap);
         surface = qemu_create_displaysurface_from(disp_width,
-                height, depth, s->line_offset,
-                s->vram_ptr + (s->start_addr * 4), byteswap);
+                height, format, s->line_offset,
+                s->vram_ptr + (s->start_addr * 4));
         dpy_gfx_replace_surface(s->con, surface);
     }
 
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 591b645439..b8901d018b 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -1052,10 +1052,12 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s)
         s->new_height != surface_height(surface) ||
         s->new_depth != surface_bits_per_pixel(surface)) {
         int stride = (s->new_depth * s->new_width) / 8;
+        pixman_format_code_t format =
+            qemu_default_pixman_format(s->new_depth, true);
         trace_vmware_setmode(s->new_width, s->new_height, s->new_depth);
         surface = qemu_create_displaysurface_from(s->new_width, s->new_height,
-                                                  s->new_depth, stride,
-                                                  s->vga.vram_ptr, false);
+                                                  format, stride,
+                                                  s->vga.vram_ptr);
         dpy_gfx_replace_surface(s->vga.con, surface);
         s->invalidated = 1;
     }
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 07ddc9deba..8a61e959a6 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -713,15 +713,17 @@ static void xenfb_update(void *opaque)
 
     /* resize if needed */
     if (xenfb->do_resize) {
+        pixman_format_code_t format;
+
         xenfb->do_resize = 0;
         switch (xenfb->depth) {
         case 16:
         case 32:
             /* console.c supported depth -> buffer can be used directly */
+            format = qemu_default_pixman_format(xenfb->depth, true);
             surface = qemu_create_displaysurface_from
-                (xenfb->width, xenfb->height, xenfb->depth,
-                 xenfb->row_stride, xenfb->pixels + xenfb->offset,
-                 false);
+                (xenfb->width, xenfb->height, format,
+                 xenfb->row_stride, xenfb->pixels + xenfb->offset);
             break;
         default:
             /* we must convert stuff */
diff --git a/include/ui/console.h b/include/ui/console.h
index 845526ed01..cde0faf6e5 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -102,8 +102,7 @@ struct QemuConsoleClass {
     ObjectClass parent_class;
 };
 
-#define QEMU_BIG_ENDIAN_FLAG    0x01
-#define QEMU_ALLOCATED_FLAG     0x02
+#define QEMU_ALLOCATED_FLAG     0x01
 
 struct PixelFormat {
     uint8_t bits_per_pixel;
@@ -119,8 +118,6 @@ struct DisplaySurface {
     pixman_format_code_t format;
     pixman_image_t *image;
     uint8_t flags;
-
-    struct PixelFormat pf;
 };
 
 typedef struct QemuUIInfo {
@@ -188,9 +185,13 @@ struct DisplayChangeListener {
 };
 
 DisplayState *init_displaystate(void);
-DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
-                                                int linesize, uint8_t *data,
-                                                bool byteswap);
+DisplaySurface *qemu_create_displaysurface_from(int width, int height,
+                                                pixman_format_code_t format,
+                                                int linesize, uint8_t *data);
+DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
+                                                    pixman_format_code_t format,
+                                                    int linesize,
+                                                    uint64_t addr);
 PixelFormat qemu_different_endianness_pixelformat(int bpp);
 PixelFormat qemu_default_pixelformat(int bpp);
 
@@ -199,10 +200,12 @@ void qemu_free_displaysurface(DisplaySurface *surface);
 
 static inline int is_surface_bgr(DisplaySurface *surface)
 {
-    if (surface->pf.bits_per_pixel == 32 && surface->pf.rshift == 0)
+    if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
+        PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
         return 1;
-    else
+    } else {
         return 0;
+    }
 }
 
 static inline int is_buffer_shared(DisplaySurface *surface)
@@ -228,6 +231,10 @@ void dpy_text_resize(QemuConsole *con, int w, int h);
 void dpy_mouse_set(QemuConsole *con, int x, int y, int on);
 void dpy_cursor_define(QemuConsole *con, QEMUCursor *cursor);
 bool dpy_cursor_define_supported(QemuConsole *con);
+void dpy_gfx_update_dirty(QemuConsole *con,
+                          MemoryRegion *address_space,
+                          uint64_t base,
+                          bool invalidate);
 
 static inline int surface_stride(DisplaySurface *s)
 {
diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index ba970f813b..381969d97b 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -33,6 +33,8 @@
 
 /* -------------------------------------------------------------------- */
 
+PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format);
+pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian);
 int qemu_pixman_get_type(int rshift, int gshift, int bshift);
 pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
 
@@ -40,6 +42,8 @@ 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 x, int y);
+void qemu_pixman_linebuf_copy(pixman_image_t *fb, int width, int x, int y,
+                              pixman_image_t *linebuf);
 pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
                                           pixman_image_t *image);
 void qemu_pixman_image_unref(pixman_image_t *image);
diff --git a/trace-events b/trace-events
index 03ac5d205c..fb58963ca8 100644
--- a/trace-events
+++ b/trace-events
@@ -1045,7 +1045,7 @@ console_txt_new(int w, int h) "%dx%d"
 console_select(int nr) "%d"
 console_refresh(int interval) "interval %d ms"
 displaysurface_create(void *display_surface, int w, int h) "surface=%p, %dx%d"
-displaysurface_create_from(void *display_surface, int w, int h, int bpp, int swap) "surface=%p, %dx%d, bpp %d, bswap %d"
+displaysurface_create_from(void *display_surface, int w, int h, uint32_t format) "surface=%p, %dx%d, format 0x%x"
 displaysurface_free(void *display_surface) "surface=%p"
 displaychangelistener_register(void *dcl, const char *name) "%p [ %s ]"
 displaychangelistener_unregister(void *dcl, const char *name) "%p [ %s ]"
diff --git a/ui/console.c b/ui/console.c
index ab8454903c..5d73d811c0 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -28,6 +28,7 @@
 #include "qmp-commands.h"
 #include "sysemu/char.h"
 #include "trace.h"
+#include "exec/memory.h"
 
 #define DEFAULT_BACKSCROLL 512
 #define CONSOLE_CURSOR_PERIOD 500
@@ -1224,61 +1225,77 @@ static QemuConsole *new_console(DisplayState *ds, console_type_t console_type,
     return s;
 }
 
-static 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)
 {
-    surface->pf = pf;
-
     qemu_pixman_image_unref(surface->image);
     surface->image = NULL;
 
-    surface->format = qemu_pixman_get_format(&pf);
-    assert(surface->format != 0);
+    surface->format = PIXMAN_x8r8g8b8;
     surface->image = pixman_image_create_bits(surface->format,
                                               width, height,
-                                              NULL, linesize);
+                                              NULL, width * 4);
     assert(surface->image != NULL);
 
-    surface->flags = newflags | QEMU_ALLOCATED_FLAG;
-#ifdef HOST_WORDS_BIGENDIAN
-    surface->flags |= QEMU_BIG_ENDIAN_FLAG;
-#endif
+    surface->flags = QEMU_ALLOCATED_FLAG;
 }
 
 DisplaySurface *qemu_create_displaysurface(int width, int height)
 {
     DisplaySurface *surface = g_new0(DisplaySurface, 1);
-    int linesize = width * 4;
 
     trace_displaysurface_create(surface, width, height);
-    qemu_alloc_display(surface, width, height, linesize,
-                       qemu_default_pixelformat(32), 0);
+    qemu_alloc_display(surface, width, height);
     return surface;
 }
 
-DisplaySurface *qemu_create_displaysurface_from(int width, int height, int bpp,
-                                                int linesize, uint8_t *data,
-                                                bool byteswap)
+DisplaySurface *qemu_create_displaysurface_from(int width, int height,
+                                                pixman_format_code_t format,
+                                                int linesize, uint8_t *data)
 {
     DisplaySurface *surface = g_new0(DisplaySurface, 1);
 
-    trace_displaysurface_create_from(surface, width, height, bpp, byteswap);
-    if (byteswap) {
-        surface->pf = qemu_different_endianness_pixelformat(bpp);
-    } else {
-        surface->pf = qemu_default_pixelformat(bpp);
-    }
-
-    surface->format = qemu_pixman_get_format(&surface->pf);
-    assert(surface->format != 0);
+    trace_displaysurface_create_from(surface, width, height, format);
+    surface->format = format;
     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
+    return surface;
+}
+
+static void qemu_unmap_displaysurface_guestmem(pixman_image_t *image,
+                                               void *unused)
+{
+    void *data = pixman_image_get_data(image);
+    uint32_t size = pixman_image_get_stride(image) *
+        pixman_image_get_height(image);
+    cpu_physical_memory_unmap(data, size, 0, 0);
+}
+
+DisplaySurface *qemu_create_displaysurface_guestmem(int width, int height,
+                                                    pixman_format_code_t format,
+                                                    int linesize, uint64_t addr)
+{
+    DisplaySurface *surface;
+    hwaddr size;
+    void *data;
+
+    if (linesize == 0) {
+        linesize = width * PIXMAN_FORMAT_BPP(format) / 8;
+    }
+
+    size = linesize * height;
+    data = cpu_physical_memory_map(addr, &size, 0);
+    if (size != linesize * height) {
+        cpu_physical_memory_unmap(data, size, 0, 0);
+        return NULL;
+    }
+
+    surface = qemu_create_displaysurface_from
+        (width, height, format, linesize, data);
+    pixman_image_set_destroy_function
+        (surface->image, qemu_unmap_displaysurface_guestmem, NULL);
 
     return surface;
 }
@@ -1557,6 +1574,67 @@ bool dpy_cursor_define_supported(QemuConsole *con)
     return false;
 }
 
+/*
+ * Call dpy_gfx_update for all dirity scanlines.  Works for
+ * DisplaySurfaces backed by guest memory (i.e. the ones created
+ * using qemu_create_displaysurface_guestmem).
+ */
+void dpy_gfx_update_dirty(QemuConsole *con,
+                          MemoryRegion *address_space,
+                          hwaddr base,
+                          bool invalidate)
+{
+    DisplaySurface *ds = qemu_console_surface(con);
+    int width = surface_stride(ds);
+    int height = surface_height(ds);
+    hwaddr size = width * height;
+    MemoryRegionSection mem_section;
+    MemoryRegion *mem;
+    ram_addr_t addr;
+    int first, last, i;
+    bool dirty;
+
+    mem_section = memory_region_find(address_space, base, size);
+    mem = mem_section.mr;
+    if (int128_get64(mem_section.size) != size ||
+        !memory_region_is_ram(mem_section.mr)) {
+        goto out;
+    }
+    assert(mem);
+
+    memory_region_sync_dirty_bitmap(mem);
+    addr = mem_section.offset_within_region;
+
+    first = -1;
+    last = -1;
+    for (i = 0; i < height; i++, addr += width) {
+        dirty = invalidate ||
+            memory_region_get_dirty(mem, addr, width, DIRTY_MEMORY_VGA);
+        if (dirty) {
+            if (first == -1) {
+                first = i;
+            }
+            last = i;
+        }
+        if (first != -1 && !dirty) {
+            assert(last != -1 && last >= first);
+            dpy_gfx_update(con, 0, first, surface_width(ds),
+                           last - first + 1);
+            first = -1;
+        }
+    }
+    if (first != -1) {
+        assert(last != -1 && last >= first);
+        dpy_gfx_update(con, 0, first, surface_width(ds),
+                       last - first + 1);
+    }
+
+    memory_region_reset_dirty(mem, mem_section.offset_within_region, size,
+                              DIRTY_MEMORY_VGA);
+out:
+    memory_region_unref(mem);
+}
+
 /***********************************************************/
 /* register display */
 
@@ -1902,124 +1980,15 @@ DisplayState *qemu_console_displaystate(QemuConsole *console)
 
 PixelFormat qemu_different_endianness_pixelformat(int bpp)
 {
-    PixelFormat pf;
-
-    memset(&pf, 0x00, sizeof(PixelFormat));
-
-    pf.bits_per_pixel = bpp;
-    pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
-    pf.depth = bpp == 32 ? 24 : bpp;
-
-    switch (bpp) {
-        case 24:
-            pf.rmask = 0x000000FF;
-            pf.gmask = 0x0000FF00;
-            pf.bmask = 0x00FF0000;
-            pf.rmax = 255;
-            pf.gmax = 255;
-            pf.bmax = 255;
-            pf.rshift = 0;
-            pf.gshift = 8;
-            pf.bshift = 16;
-            pf.rbits = 8;
-            pf.gbits = 8;
-            pf.bbits = 8;
-            break;
-        case 32:
-            pf.rmask = 0x0000FF00;
-            pf.gmask = 0x00FF0000;
-            pf.bmask = 0xFF000000;
-            pf.amask = 0x00000000;
-            pf.amax = 255;
-            pf.rmax = 255;
-            pf.gmax = 255;
-            pf.bmax = 255;
-            pf.ashift = 0;
-            pf.rshift = 8;
-            pf.gshift = 16;
-            pf.bshift = 24;
-            pf.rbits = 8;
-            pf.gbits = 8;
-            pf.bbits = 8;
-            pf.abits = 8;
-            break;
-        default:
-            break;
-    }
+    pixman_format_code_t fmt = qemu_default_pixman_format(bpp, false);
+    PixelFormat pf = qemu_pixelformat_from_pixman(fmt);
     return pf;
 }
 
 PixelFormat qemu_default_pixelformat(int bpp)
 {
-    PixelFormat pf;
-
-    memset(&pf, 0x00, sizeof(PixelFormat));
-
-    pf.bits_per_pixel = bpp;
-    pf.bytes_per_pixel = DIV_ROUND_UP(bpp, 8);
-    pf.depth = bpp == 32 ? 24 : bpp;
-
-    switch (bpp) {
-        case 15:
-            pf.bits_per_pixel = 16;
-            pf.rmask = 0x00007c00;
-            pf.gmask = 0x000003E0;
-            pf.bmask = 0x0000001F;
-            pf.rmax = 31;
-            pf.gmax = 31;
-            pf.bmax = 31;
-            pf.rshift = 10;
-            pf.gshift = 5;
-            pf.bshift = 0;
-            pf.rbits = 5;
-            pf.gbits = 5;
-            pf.bbits = 5;
-            break;
-        case 16:
-            pf.rmask = 0x0000F800;
-            pf.gmask = 0x000007E0;
-            pf.bmask = 0x0000001F;
-            pf.rmax = 31;
-            pf.gmax = 63;
-            pf.bmax = 31;
-            pf.rshift = 11;
-            pf.gshift = 5;
-            pf.bshift = 0;
-            pf.rbits = 5;
-            pf.gbits = 6;
-            pf.bbits = 5;
-            break;
-        case 24:
-            pf.rmask = 0x00FF0000;
-            pf.gmask = 0x0000FF00;
-            pf.bmask = 0x000000FF;
-            pf.rmax = 255;
-            pf.gmax = 255;
-            pf.bmax = 255;
-            pf.rshift = 16;
-            pf.gshift = 8;
-            pf.bshift = 0;
-            pf.rbits = 8;
-            pf.gbits = 8;
-            pf.bbits = 8;
-            break;
-        case 32:
-            pf.rmask = 0x00FF0000;
-            pf.gmask = 0x0000FF00;
-            pf.bmask = 0x000000FF;
-            pf.rmax = 255;
-            pf.gmax = 255;
-            pf.bmax = 255;
-            pf.rshift = 16;
-            pf.gshift = 8;
-            pf.bshift = 0;
-            pf.rbits = 8;
-            pf.gbits = 8;
-            pf.bbits = 8;
-            break;
-        default:
-            break;
-    }
+    pixman_format_code_t fmt = qemu_default_pixman_format(bpp, true);
+    PixelFormat pf = qemu_pixelformat_from_pixman(fmt);
     return pf;
 }
 
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 254bd8ce10..30c7fdd011 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -6,6 +6,87 @@
 #include "qemu-common.h"
 #include "ui/console.h"
 
+PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format)
+{
+    PixelFormat pf;
+    uint8_t bpp;
+
+    bpp = pf.bits_per_pixel = PIXMAN_FORMAT_BPP(format);
+    pf.bytes_per_pixel = PIXMAN_FORMAT_BPP(format) / 8;
+    pf.depth = PIXMAN_FORMAT_DEPTH(format);
+
+    pf.abits = PIXMAN_FORMAT_A(format);
+    pf.rbits = PIXMAN_FORMAT_R(format);
+    pf.gbits = PIXMAN_FORMAT_G(format);
+    pf.bbits = PIXMAN_FORMAT_B(format);
+
+    switch (PIXMAN_FORMAT_TYPE(format)) {
+    case PIXMAN_TYPE_ARGB:
+        pf.ashift = pf.bbits + pf.gbits + pf.rbits;
+        pf.rshift = pf.bbits + pf.gbits;
+        pf.gshift = pf.bbits;
+        pf.bshift = 0;
+        break;
+    case PIXMAN_TYPE_ABGR:
+        pf.ashift = pf.rbits + pf.gbits + pf.bbits;
+        pf.bshift = pf.rbits + pf.gbits;
+        pf.gshift = pf.rbits;
+        pf.rshift = 0;
+        break;
+    case PIXMAN_TYPE_BGRA:
+	pf.bshift = bpp - pf.bbits;
+        pf.gshift = bpp - (pf.bbits + pf.gbits);
+        pf.rshift = bpp - (pf.bbits + pf.gbits + pf.rbits);
+        pf.ashift = 0;
+        break;
+    case PIXMAN_TYPE_RGBA:
+        pf.rshift = bpp - pf.rbits;
+        pf.gshift = bpp - (pf.rbits + pf.gbits);
+        pf.bshift = bpp - (pf.rbits + pf.gbits + pf.bbits);
+        pf.ashift = 0;
+        break;
+    default:
+        g_assert_not_reached();
+        break;
+    }
+
+    pf.amax = (1 << pf.abits) - 1;
+    pf.rmax = (1 << pf.rbits) - 1;
+    pf.gmax = (1 << pf.gbits) - 1;
+    pf.bmax = (1 << pf.bbits) - 1;
+    pf.amask = pf.amax << pf.ashift;
+    pf.rmask = pf.rmax << pf.rshift;
+    pf.gmask = pf.gmax << pf.gshift;
+    pf.bmask = pf.bmax << pf.bshift;
+
+    return pf;
+}
+
+pixman_format_code_t qemu_default_pixman_format(int bpp, bool native_endian)
+{
+    if (native_endian) {
+        switch (bpp) {
+        case 15:
+            return PIXMAN_x1r5g5b5;
+        case 16:
+            return PIXMAN_r5g6b5;
+        case 24:
+            return PIXMAN_r8g8b8;
+        case 32:
+            return PIXMAN_x8r8g8b8;
+        }
+    } else {
+        switch (bpp) {
+        case 24:
+            return PIXMAN_b8g8r8;
+        case 32:
+            return PIXMAN_b8g8r8a8;
+        break;
+        }
+    }
+    g_assert_not_reached();
+}
+
 int qemu_pixman_get_type(int rshift, int gshift, int bshift)
 {
     int type = PIXMAN_TYPE_OTHER;
@@ -52,6 +133,7 @@ pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format,
     return image;
 }
 
+/* fill linebuf from framebuffer */
 void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
                               int width, int x, int y)
 {
@@ -59,6 +141,14 @@ void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,
                            x, y, 0, 0, 0, 0, width, 1);
 }
 
+/* copy linebuf to framebuffer */
+void qemu_pixman_linebuf_copy(pixman_image_t *fb, int width, int x, int y,
+                              pixman_image_t *linebuf)
+{
+    pixman_image_composite(PIXMAN_OP_SRC, linebuf, NULL, fb,
+                           0, 0, 0, 0, x, y, width, 1);
+}
+
 pixman_image_t *qemu_pixman_mirror_create(pixman_format_code_t format,
                                           pixman_image_t *image)
 {
diff --git a/ui/sdl.c b/ui/sdl.c
index 4e7f920e37..94c1d9dc3a 100644
--- a/ui/sdl.c
+++ b/ui/sdl.c
@@ -127,6 +127,7 @@ static void do_sdl_resize(int width, int height, int bpp)
 static void sdl_switch(DisplayChangeListener *dcl,
                        DisplaySurface *new_surface)
 {
+    PixelFormat pf = qemu_pixelformat_from_pixman(new_surface->format);
 
     /* temporary hack: allows to call sdl_switch to handle scaling changes */
     if (new_surface) {
@@ -148,8 +149,8 @@ static void sdl_switch(DisplayChangeListener *dcl,
         (surface_data(surface),
          surface_width(surface), surface_height(surface),
          surface_bits_per_pixel(surface), surface_stride(surface),
-         surface->pf.rmask, surface->pf.gmask,
-         surface->pf.bmask, surface->pf.amask);
+         pf.rmask, pf.gmask,
+         pf.bmask, pf.amask);
 }
 
 /* generic keyboard conversion */
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index f02352cc46..3d1b5cd066 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -220,8 +220,7 @@ tight_detect_smooth_image24(VncState *vs, int w, int h)
         unsigned int errors;                                            \
         unsigned char *buf = vs->tight.tight.buffer;                    \
                                                                         \
-        endian = 0; /* FIXME: ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \
-                      (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); */ \
+        endian = 0; /* FIXME */                                         \
                                                                         \
                                                                         \
         max[0] = vs->client_pf.rmax;                                  \
@@ -563,8 +562,7 @@ 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 (1 /* FIXME: (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
-             (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) */) {
+    if (1 /* FIXME */) {
         shift[0] = vs->client_pf.rshift;
         shift[1] = vs->client_pf.gshift;
         shift[2] = vs->client_pf.bshift;
@@ -621,8 +619,7 @@ tight_filter_gradient24(VncState *vs, uint8_t *buf, int w, int h)
                                                                         \
         memset (vs->tight.gradient.buffer, 0, w * 3 * sizeof(int));     \
                                                                         \
-        endian = 0; /* FIXME: ((vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) != \
-                       (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG)); */ \
+        endian = 0; /* FIXME */                                         \
                                                                         \
         max[0] = vs->client_pf.rmax;                                    \
         max[1] = vs->client_pf.gmax;                                    \
@@ -898,8 +895,7 @@ static void tight_pack24(VncState *vs, uint8_t *buf, size_t count, size_t *ret)
 
     buf32 = (uint32_t *)buf;
 
-    if (1 /* FIXME: (vs->clientds.flags & QEMU_BIG_ENDIAN_FLAG) ==
-             (vs->ds->surface->flags & QEMU_BIG_ENDIAN_FLAG) */) {
+    if (1 /* FIXME */) {
         rshift = vs->client_pf.rshift;
         gshift = vs->client_pf.gshift;
         bshift = vs->client_pf.bshift;