qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued
@ 2014-09-02  8:00 Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 01/14] console: add qemu_pixelformat_from_pixman Gerd Hoffmann
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Here is a two-in-one patch series.

The first part makes the console code use pixman format codes
internally.  It also adds some helper functions for gfx emulation
code.  If you wanna see that in action check the second part of the
series ;)  I consider the first part being close to ready for merging.

The second part starts switching over the pl110 emulation to use pixman
for pixel ops.  For framebuffer formats which pixman can handle natively
we can even avoid copying around the framebuffer content and create a
DisplaySurface backed by guest memory.  Tested with linux guests and
pl110 framebuffer driver, which covers only the simple lblp
(little-endian-bytes + little-endian-pixels) + bgr case.  It is not
complete yet, but should already show nicely how one can use pixman in
the display emulation code.

cheers,
  Gerd

Benjamin Herrenschmidt (1):
  console: Remove unused QEMU_BIG_ENDIAN_FLAG

Gerd Hoffmann (13):
  console: add qemu_pixelformat_from_pixman
  console: add qemu_default_pixman_format
  console: reimplement qemu_default_pixelformat
  console: stop using PixelFormat
  console: add qemu_create_displaysurface_guestmem
  console: add dpy_gfx_update_dirty
  console: add qemu_pixman_linebuf_copy
  pl110: add framebuffer_update_display_swap_pixman
  pl100: Drop support for depths other than 32bpp.
  pl110: move resize
  [wip] pl110: start using pixman
  [wip] pl110: switch some conversions to swap+pixman mode
  [wip] pl110: start handling paletted images via pixman

 hw/display/framebuffer.c    | 131 +++++++++++++++++++++++
 hw/display/framebuffer.h    |  18 ++++
 hw/display/pl110.c          | 146 ++++++++++++-------------
 hw/display/pl110_template.h | 181 ++++++++++++++++++-------------
 hw/display/qxl-render.c     |   7 +-
 hw/display/vga.c            |  12 ++-
 hw/display/vmware_vga.c     |   6 +-
 hw/display/xenfb.c          |   8 +-
 include/ui/console.h        |  25 +++--
 include/ui/qemu-pixman.h    |   4 +
 trace-events                |   2 +-
 ui/console.c                | 253 +++++++++++++++++++-------------------------
 ui/qemu-pixman.c            |  90 ++++++++++++++++
 ui/sdl.c                    |   5 +-
 ui/vnc-enc-tight.c          |  12 +--
 15 files changed, 570 insertions(+), 330 deletions(-)

-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 01/14] console: add qemu_pixelformat_from_pixman
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 02/14] console: add qemu_default_pixman_format Gerd Hoffmann
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

Function to convert pixman format codes to qemu PixelFormat.

[ Benjamin Herrenschmidt: fix BGRA+RGBA shifts ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/qemu-pixman.h |  1 +
 ui/qemu-pixman.c         | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 57 insertions(+)

diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index ba970f8..090a3e2 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -33,6 +33,7 @@
 
 /* -------------------------------------------------------------------- */
 
+PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format);
 int qemu_pixman_get_type(int rshift, int gshift, int bshift);
 pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf);
 
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 254bd8c..bdc1439 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -6,6 +6,62 @@
 #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;
+}
+
 int qemu_pixman_get_type(int rshift, int gshift, int bshift)
 {
     int type = PIXMAN_TYPE_OTHER;
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 02/14] console: add qemu_default_pixman_format
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 01/14] console: add qemu_pixelformat_from_pixman Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 03/14] console: reimplement qemu_default_pixelformat Gerd Hoffmann
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

Function returning the default pixman format for a given depth.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/qemu-pixman.h |  1 +
 ui/qemu-pixman.c         | 25 +++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index 090a3e2..80ed94a 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -34,6 +34,7 @@
 /* -------------------------------------------------------------------- */
 
 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);
 
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index bdc1439..5d8bd46 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -62,6 +62,31 @@ PixelFormat qemu_pixelformat_from_pixman(pixman_format_code_t format)
     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;
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 03/14] console: reimplement qemu_default_pixelformat
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 01/14] console: add qemu_pixelformat_from_pixman Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 02/14] console: add qemu_default_pixman_format Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 04/14] console: stop using PixelFormat Gerd Hoffmann
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

Use the new qemu_pixelformat_from_pixman and qemu_default_pixman_format
functions to reimplement qemu_default_pixelformat
(qemu_different_endianness_pixelformat too).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 ui/console.c | 117 ++---------------------------------------------------------
 1 file changed, 4 insertions(+), 113 deletions(-)

diff --git a/ui/console.c b/ui/console.c
index ab84549..28711a4 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1902,124 +1902,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;
 }
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 04/14] console: stop using PixelFormat
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 03/14] console: reimplement qemu_default_pixelformat Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 05/14] console: add qemu_create_displaysurface_guestmem Gerd Hoffmann
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

With this patch the qemu console core stops using PixelFormat and pixman
format codes side-by-side, pixman format code is the primary way to
specify the DisplaySurface format:

 * DisplaySurface stops carrying a PixelFormat field.
 * qemu_create_displaysurface_from() expects a pixman format now.

Functions to convert PixelFormat to pixman_format_code_t (and back)
exist for those who still use PixelFormat.   As PixelFormat allows
easy access to masks and shifts it will probably continue to exist.

[ xenfb added by Benjamin Herrenschmidt ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/qxl-render.c |  7 ++++---
 hw/display/vga.c        | 12 ++++++++----
 hw/display/vmware_vga.c |  6 ++++--
 hw/display/xenfb.c      |  8 +++++---
 include/ui/console.h    | 14 +++++++-------
 trace-events            |  2 +-
 ui/console.c            | 33 ++++++++++-----------------------
 ui/sdl.c                |  5 +++--
 8 files changed, 42 insertions(+), 45 deletions(-)

diff --git a/hw/display/qxl-render.c b/hw/display/qxl-render.c
index cc2c2b1..d79f5a3 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 65dab8d..948265a 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1689,9 +1689,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);
@@ -1707,9 +1709,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 591b645..b8901d0 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 07ddc9d..8a61e95 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 845526e..68ac362 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -119,8 +119,6 @@ struct DisplaySurface {
     pixman_format_code_t format;
     pixman_image_t *image;
     uint8_t flags;
-
-    struct PixelFormat pf;
 };
 
 typedef struct QemuUIInfo {
@@ -188,9 +186,9 @@ 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);
 PixelFormat qemu_different_endianness_pixelformat(int bpp);
 PixelFormat qemu_default_pixelformat(int bpp);
 
@@ -199,10 +197,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)
diff --git a/trace-events b/trace-events
index 03ac5d2..fb58963 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 28711a4..968aaaf 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1224,22 +1224,18 @@ 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;
+    surface->flags = QEMU_ALLOCATED_FLAG;
 #ifdef HOST_WORDS_BIGENDIAN
     surface->flags |= QEMU_BIG_ENDIAN_FLAG;
 #endif
@@ -1248,29 +1244,20 @@ static void qemu_alloc_display(DisplaySurface *surface, int width, int height,
 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);
diff --git a/ui/sdl.c b/ui/sdl.c
index 4e7f920..94c1d9d 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 */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 05/14] console: add qemu_create_displaysurface_guestmem
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 04/14] console: stop using PixelFormat Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 06/14] console: add dpy_gfx_update_dirty Gerd Hoffmann
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

This patch adds a qemu_create_displaysurface_guestmem helper function.
Works simliar to qemu_create_displaysurface_from, but accepts a
guest address instead of a host pointer and it handles
cpu_physical_memory_{map,unmap} for you.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |  4 ++++
 ui/console.c         | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/include/ui/console.h b/include/ui/console.h
index 68ac362..61901f7 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -189,6 +189,10 @@ DisplayState *init_displaystate(void);
 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);
 
diff --git a/ui/console.c b/ui/console.c
index 968aaaf..654c0d3 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
@@ -1270,6 +1271,42 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height,
     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;
+}
+
 static DisplaySurface *qemu_create_message_surface(int w, int h,
                                                    const char *msg)
 {
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 06/14] console: add dpy_gfx_update_dirty
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 05/14] console: add qemu_create_displaysurface_guestmem Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 07/14] console: add qemu_pixman_linebuf_copy Gerd Hoffmann
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

Calls dpy_gfx_update for all dirty scanlines. Works for
DisplaySurfaces backed by guest memory (i.e. the ones created
using qemu_create_displaysurface_guestmem).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/console.h |  4 ++++
 ui/console.c         | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/include/ui/console.h b/include/ui/console.h
index 61901f7..58a7d4b 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -232,6 +232,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/ui/console.c b/ui/console.c
index 654c0d3..d1342ca 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1581,6 +1581,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 */
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 07/14] console: add qemu_pixman_linebuf_copy
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 06/14] console: add dpy_gfx_update_dirty Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 08/14] console: Remove unused QEMU_BIG_ENDIAN_FLAG Gerd Hoffmann
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

Helper function for copying data from linebuf to framebuffer using
pixman, possibly converting in case src and dst formats differ.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 include/ui/qemu-pixman.h | 2 ++
 ui/qemu-pixman.c         | 9 +++++++++
 2 files changed, 11 insertions(+)

diff --git a/include/ui/qemu-pixman.h b/include/ui/qemu-pixman.h
index 80ed94a..381969d 100644
--- a/include/ui/qemu-pixman.h
+++ b/include/ui/qemu-pixman.h
@@ -42,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/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 5d8bd46..30c7fdd 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -133,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)
 {
@@ -140,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)
 {
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 08/14] console: Remove unused QEMU_BIG_ENDIAN_FLAG
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 07/14] console: add qemu_pixman_linebuf_copy Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 09/14] pl110: add framebuffer_update_display_swap_pixman Gerd Hoffmann
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Anthony Liguori

From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

If we need to, we should use the pixman formats instead but for
now this is unused except in commented out code so take it out
to avoid further confusion about surface endianness.

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 include/ui/console.h |  3 +--
 ui/console.c         |  7 -------
 ui/vnc-enc-tight.c   | 12 ++++--------
 3 files changed, 5 insertions(+), 17 deletions(-)

diff --git a/include/ui/console.h b/include/ui/console.h
index 58a7d4b..cde0faf 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;
diff --git a/ui/console.c b/ui/console.c
index d1342ca..5d73d81 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -1237,9 +1237,6 @@ static void qemu_alloc_display(DisplaySurface *surface, int width, int height)
     assert(surface->image != NULL);
 
     surface->flags = QEMU_ALLOCATED_FLAG;
-#ifdef HOST_WORDS_BIGENDIAN
-    surface->flags |= QEMU_BIG_ENDIAN_FLAG;
-#endif
 }
 
 DisplaySurface *qemu_create_displaysurface(int width, int height)
@@ -1264,10 +1261,6 @@ DisplaySurface *qemu_create_displaysurface_from(int width, int height,
                                               (void *)data, linesize);
     assert(surface->image != NULL);
 
-#ifdef HOST_WORDS_BIGENDIAN
-    surface->flags = QEMU_BIG_ENDIAN_FLAG;
-#endif
-
     return surface;
 }
 
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index f02352c..3d1b5cd 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;
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 09/14] pl110: add framebuffer_update_display_swap_pixman
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (7 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 08/14] console: Remove unused QEMU_BIG_ENDIAN_FLAG Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 10/14] pl100: Drop support for depths other than 32bpp Gerd Hoffmann
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Works like framebuffer_update_display, but accepts a (newly introduced)
swapmode and a pixman format instead of a callback function.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/framebuffer.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++
 hw/display/framebuffer.h |  17 +++++++
 2 files changed, 146 insertions(+)

diff --git a/hw/display/framebuffer.c b/hw/display/framebuffer.c
index 4546e42..d3a2c70 100644
--- a/hw/display/framebuffer.c
+++ b/hw/display/framebuffer.c
@@ -111,3 +111,132 @@ void framebuffer_update_display(
 out:
     memory_region_unref(mem);
 }
+
+static void framebuffer_swap(enum framebuffer_swapmode swapmode,
+                             pixman_image_t *dest, void *src)
+{
+    int swaps;
+    uint32_t *s32, *d32;
+    uint16_t *s16, *d16;
+
+    switch (swapmode) {
+    case FB_SWAP_NONE:
+        memcpy(pixman_image_get_data(dest),
+               src,
+               pixman_image_get_stride(dest));
+        break;
+    case FB_SWAP_16_BYTES:
+        swaps = pixman_image_get_stride(dest) / 2;
+        s16 = src;
+        d16 = (void*)pixman_image_get_data(dest);
+        while (swaps) {
+            *d16 = bswap16(*s16);
+            s16++; d16++; swaps--;
+        }
+        break;
+    case FB_SWAP_32_BYTES:
+        swaps = pixman_image_get_stride(dest) / 4;
+        s32 = src;
+        d32 = pixman_image_get_data(dest);
+        while (swaps) {
+            *d32 = bswap32(*s32);
+            s32++; d32++; swaps--;
+        }
+        break;
+    case FB_SWAP_32_WORDS:
+        swaps = pixman_image_get_stride(dest) / 4;
+        s32 = src;
+        d32 = pixman_image_get_data(dest);
+        while (swaps) {
+            *d32 = (((*s32 & 0x0000ffff) << 16) |
+                    ((*s32 & 0xffff0000) >> 16));
+            s32++; d32++; swaps--;
+        }
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+
+void framebuffer_update_display_swap_pixman(
+    DisplaySurface *ds,
+    MemoryRegion *address_space,
+    hwaddr base,
+    enum framebuffer_swapmode swapmode,
+    pixman_format_code_t format,
+    int invalidate, /* nonzero to redraw the whole image.  */
+    int *first_row, /* Input and output.  */
+    int *last_row /* Output only */)
+{
+    int cols = surface_width(ds);
+    int rows = surface_height(ds);
+    int src_width = cols * PIXMAN_FORMAT_BPP(format) / 8;
+    pixman_image_t *linebuf;
+    hwaddr src_len;
+    uint8_t *src;
+    uint8_t *src_base;
+    int first, last = 0;
+    int dirty;
+    int i;
+    ram_addr_t addr;
+    MemoryRegionSection mem_section;
+    MemoryRegion *mem;
+
+    i = *first_row;
+    *first_row = -1;
+    src_len = src_width * rows;
+
+    mem_section = memory_region_find(address_space, base, src_len);
+    mem = mem_section.mr;
+    if (int128_get64(mem_section.size) != src_len ||
+        !memory_region_is_ram(mem_section.mr)) {
+        goto out;
+    }
+    assert(mem);
+    assert(mem_section.offset_within_address_space == base);
+
+    memory_region_sync_dirty_bitmap(mem);
+    src_base = cpu_physical_memory_map(base, &src_len, 0);
+    /* If we can't map the framebuffer then bail.  We could try harder,
+       but it's not really worth it as dirty flag tracking will probably
+       already have failed above.  */
+    if (!src_base)
+        goto out;
+    if (src_len != src_width * rows) {
+        cpu_physical_memory_unmap(src_base, src_len, 0, 0);
+        goto out;
+    }
+    src = src_base;
+    first = -1;
+    addr = mem_section.offset_within_region;
+
+    addr += i * src_width;
+    src += i * src_width;
+
+    linebuf = qemu_pixman_linebuf_create(format, cols);
+    for (; i < rows; i++) {
+        dirty = memory_region_get_dirty(mem, addr, src_width,
+                                        DIRTY_MEMORY_VGA);
+        if (dirty || invalidate) {
+            framebuffer_swap(swapmode, linebuf, src);
+            qemu_pixman_linebuf_copy(ds->image, cols, 0, i, linebuf);
+            if (first == -1)
+                first = i;
+            last = i;
+        }
+        addr += src_width;
+        src += src_width;
+    }
+    qemu_pixman_image_unref(linebuf);
+
+    cpu_physical_memory_unmap(src_base, src_len, 0, 0);
+    if (first < 0) {
+        goto out;
+    }
+    memory_region_reset_dirty(mem, mem_section.offset_within_region, src_len,
+                              DIRTY_MEMORY_VGA);
+    *first_row = first;
+    *last_row = last;
+out:
+    memory_region_unref(mem);
+}
diff --git a/hw/display/framebuffer.h b/hw/display/framebuffer.h
index 6eae035..6ee6df5 100644
--- a/hw/display/framebuffer.h
+++ b/hw/display/framebuffer.h
@@ -22,4 +22,21 @@ void framebuffer_update_display(
     int *first_row,
     int *last_row);
 
+enum framebuffer_swapmode {
+    FB_SWAP_NONE = 0,
+    FB_SWAP_16_BYTES,
+    FB_SWAP_32_BYTES,
+    FB_SWAP_32_WORDS,
+};
+
+void framebuffer_update_display_swap_pixman(
+    DisplaySurface *ds,
+    MemoryRegion *address_space,
+    hwaddr base,
+    enum framebuffer_swapmode,
+    pixman_format_code_t format,
+    int invalidate, /* nonzero to redraw the whole image.  */
+    int *first_row, /* Input and output.  */
+    int *last_row /* Output only */);
+
 #endif
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 10/14] pl100: Drop support for depths other than 32bpp.
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (8 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 09/14] pl110: add framebuffer_update_display_swap_pixman Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 11/14] pl110: move resize Gerd Hoffmann
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

DisplaySurfaces created by qemu_create_displaysurface (called indirectly
via by qemu_console_resize) are always 32bpp in host byte order.  So
this is the only format we have to support when converting the guest
framebuffer for the host user interface (i.e. gtk / vnc / ...).

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/pl110.c          |  59 +++-----------------
 hw/display/pl110_template.h | 133 ++++++++++++++++++++------------------------
 2 files changed, 67 insertions(+), 125 deletions(-)

diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index c574cf1..78b146b 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -112,15 +112,6 @@ static const unsigned char *idregs[] = {
     pl111_id
 };
 
-#define BITS 8
-#include "pl110_template.h"
-#define BITS 15
-#include "pl110_template.h"
-#define BITS 16
-#include "pl110_template.h"
-#define BITS 24
-#include "pl110_template.h"
-#define BITS 32
 #include "pl110_template.h"
 
 static int pl110_enabled(PL110State *s)
@@ -133,7 +124,6 @@ static void pl110_update_display(void *opaque)
     PL110State *s = (PL110State *)opaque;
     SysBusDevice *sbd;
     DisplaySurface *surface = qemu_console_surface(s->con);
-    drawfn* fntable;
     drawfn fn;
     int dest_width;
     int src_width;
@@ -147,33 +137,6 @@ static void pl110_update_display(void *opaque)
 
     sbd = SYS_BUS_DEVICE(s);
 
-    switch (surface_bits_per_pixel(surface)) {
-    case 0:
-        return;
-    case 8:
-        fntable = pl110_draw_fn_8;
-        dest_width = 1;
-        break;
-    case 15:
-        fntable = pl110_draw_fn_15;
-        dest_width = 2;
-        break;
-    case 16:
-        fntable = pl110_draw_fn_16;
-        dest_width = 2;
-        break;
-    case 24:
-        fntable = pl110_draw_fn_24;
-        dest_width = 3;
-        break;
-    case 32:
-        fntable = pl110_draw_fn_32;
-        dest_width = 4;
-        break;
-    default:
-        fprintf(stderr, "pl110: Bad color depth\n");
-        exit(1);
-    }
     if (s->cr & PL110_CR_BGR)
         bpp_offset = 0;
     else
@@ -208,11 +171,11 @@ static void pl110_update_display(void *opaque)
     }
 
     if (s->cr & PL110_CR_BEBO)
-        fn = fntable[s->bpp + 8 + bpp_offset];
+        fn = pl110_draw_fn[s->bpp + 8 + bpp_offset];
     else if (s->cr & PL110_CR_BEPO)
-        fn = fntable[s->bpp + 16 + bpp_offset];
+        fn = pl110_draw_fn[s->bpp + 16 + bpp_offset];
     else
-        fn = fntable[s->bpp + bpp_offset];
+        fn = pl110_draw_fn[s->bpp + bpp_offset];
 
     src_width = s->cols;
     switch (s->bpp) {
@@ -236,7 +199,9 @@ static void pl110_update_display(void *opaque)
         src_width <<= 2;
         break;
     }
-    dest_width *= s->cols;
+
+    g_assert(surface_bits_per_pixel(surface) == 32);
+    dest_width = 4 * s->cols;
     first = 0;
     framebuffer_update_display(surface, sysbus_address_space(sbd),
                                s->upbase, s->cols, s->rows,
@@ -277,19 +242,11 @@ static void pl110_update_palette(PL110State *s, int n)
         /* The I bit is ignored.  */
         raw >>= 6;
         switch (surface_bits_per_pixel(surface)) {
-        case 8:
-            s->palette[n] = rgb_to_pixel8(r, g, b);
-            break;
-        case 15:
-            s->palette[n] = rgb_to_pixel15(r, g, b);
-            break;
-        case 16:
-            s->palette[n] = rgb_to_pixel16(r, g, b);
-            break;
-        case 24:
         case 32:
             s->palette[n] = rgb_to_pixel32(r, g, b);
             break;
+        default:
+            g_assert_not_reached();
         }
         n++;
     }
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
index 36ba791..5afc64c 100644
--- a/hw/display/pl110_template.h
+++ b/hw/display/pl110_template.h
@@ -11,22 +11,7 @@
 
 #ifndef ORDER
 
-#if BITS == 8
-#define COPY_PIXEL(to, from) *(to++) = from
-#elif BITS == 15 || BITS == 16
-#define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0)
-#elif BITS == 24
-#define COPY_PIXEL(to, from)    \
-    do {                        \
-        *(to++) = from;         \
-        *(to++) = (from) >> 8;  \
-        *(to++) = (from) >> 16; \
-    } while (0)
-#elif BITS == 32
 #define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
-#else
-#error unknown bit depth
-#endif
 
 #undef RGB
 #define BORDER bgr
@@ -47,61 +32,61 @@
 #include "pl110_template.h"
 #undef BORDER
 
-static drawfn glue(pl110_draw_fn_,BITS)[48] =
+static drawfn pl110_draw_fn[48] =
 {
-    glue(pl110_draw_line1_lblp_bgr,BITS),
-    glue(pl110_draw_line2_lblp_bgr,BITS),
-    glue(pl110_draw_line4_lblp_bgr,BITS),
-    glue(pl110_draw_line8_lblp_bgr,BITS),
-    glue(pl110_draw_line16_555_lblp_bgr,BITS),
-    glue(pl110_draw_line32_lblp_bgr,BITS),
-    glue(pl110_draw_line16_lblp_bgr,BITS),
-    glue(pl110_draw_line12_lblp_bgr,BITS),
+    pl110_draw_line1_lblp_bgr,
+    pl110_draw_line2_lblp_bgr,
+    pl110_draw_line4_lblp_bgr,
+    pl110_draw_line8_lblp_bgr,
+    pl110_draw_line16_555_lblp_bgr,
+    pl110_draw_line32_lblp_bgr,
+    pl110_draw_line16_lblp_bgr,
+    pl110_draw_line12_lblp_bgr,
 
-    glue(pl110_draw_line1_bbbp_bgr,BITS),
-    glue(pl110_draw_line2_bbbp_bgr,BITS),
-    glue(pl110_draw_line4_bbbp_bgr,BITS),
-    glue(pl110_draw_line8_bbbp_bgr,BITS),
-    glue(pl110_draw_line16_555_bbbp_bgr,BITS),
-    glue(pl110_draw_line32_bbbp_bgr,BITS),
-    glue(pl110_draw_line16_bbbp_bgr,BITS),
-    glue(pl110_draw_line12_bbbp_bgr,BITS),
+    pl110_draw_line1_bbbp_bgr,
+    pl110_draw_line2_bbbp_bgr,
+    pl110_draw_line4_bbbp_bgr,
+    pl110_draw_line8_bbbp_bgr,
+    pl110_draw_line16_555_bbbp_bgr,
+    pl110_draw_line32_bbbp_bgr,
+    pl110_draw_line16_bbbp_bgr,
+    pl110_draw_line12_bbbp_bgr,
 
-    glue(pl110_draw_line1_lbbp_bgr,BITS),
-    glue(pl110_draw_line2_lbbp_bgr,BITS),
-    glue(pl110_draw_line4_lbbp_bgr,BITS),
-    glue(pl110_draw_line8_lbbp_bgr,BITS),
-    glue(pl110_draw_line16_555_lbbp_bgr,BITS),
-    glue(pl110_draw_line32_lbbp_bgr,BITS),
-    glue(pl110_draw_line16_lbbp_bgr,BITS),
-    glue(pl110_draw_line12_lbbp_bgr,BITS),
+    pl110_draw_line1_lbbp_bgr,
+    pl110_draw_line2_lbbp_bgr,
+    pl110_draw_line4_lbbp_bgr,
+    pl110_draw_line8_lbbp_bgr,
+    pl110_draw_line16_555_lbbp_bgr,
+    pl110_draw_line32_lbbp_bgr,
+    pl110_draw_line16_lbbp_bgr,
+    pl110_draw_line12_lbbp_bgr,
 
-    glue(pl110_draw_line1_lblp_rgb,BITS),
-    glue(pl110_draw_line2_lblp_rgb,BITS),
-    glue(pl110_draw_line4_lblp_rgb,BITS),
-    glue(pl110_draw_line8_lblp_rgb,BITS),
-    glue(pl110_draw_line16_555_lblp_rgb,BITS),
-    glue(pl110_draw_line32_lblp_rgb,BITS),
-    glue(pl110_draw_line16_lblp_rgb,BITS),
-    glue(pl110_draw_line12_lblp_rgb,BITS),
+    pl110_draw_line1_lblp_rgb,
+    pl110_draw_line2_lblp_rgb,
+    pl110_draw_line4_lblp_rgb,
+    pl110_draw_line8_lblp_rgb,
+    pl110_draw_line16_555_lblp_rgb,
+    pl110_draw_line32_lblp_rgb,
+    pl110_draw_line16_lblp_rgb,
+    pl110_draw_line12_lblp_rgb,
 
-    glue(pl110_draw_line1_bbbp_rgb,BITS),
-    glue(pl110_draw_line2_bbbp_rgb,BITS),
-    glue(pl110_draw_line4_bbbp_rgb,BITS),
-    glue(pl110_draw_line8_bbbp_rgb,BITS),
-    glue(pl110_draw_line16_555_bbbp_rgb,BITS),
-    glue(pl110_draw_line32_bbbp_rgb,BITS),
-    glue(pl110_draw_line16_bbbp_rgb,BITS),
-    glue(pl110_draw_line12_bbbp_rgb,BITS),
+    pl110_draw_line1_bbbp_rgb,
+    pl110_draw_line2_bbbp_rgb,
+    pl110_draw_line4_bbbp_rgb,
+    pl110_draw_line8_bbbp_rgb,
+    pl110_draw_line16_555_bbbp_rgb,
+    pl110_draw_line32_bbbp_rgb,
+    pl110_draw_line16_bbbp_rgb,
+    pl110_draw_line12_bbbp_rgb,
 
-    glue(pl110_draw_line1_lbbp_rgb,BITS),
-    glue(pl110_draw_line2_lbbp_rgb,BITS),
-    glue(pl110_draw_line4_lbbp_rgb,BITS),
-    glue(pl110_draw_line8_lbbp_rgb,BITS),
-    glue(pl110_draw_line16_555_lbbp_rgb,BITS),
-    glue(pl110_draw_line32_lbbp_rgb,BITS),
-    glue(pl110_draw_line16_lbbp_rgb,BITS),
-    glue(pl110_draw_line12_lbbp_rgb,BITS),
+    pl110_draw_line1_lbbp_rgb,
+    pl110_draw_line2_lbbp_rgb,
+    pl110_draw_line4_lbbp_rgb,
+    pl110_draw_line8_lbbp_rgb,
+    pl110_draw_line16_555_lbbp_rgb,
+    pl110_draw_line32_lbbp_rgb,
+    pl110_draw_line16_lbbp_rgb,
+    pl110_draw_line12_lbbp_rgb,
 };
 
 #undef BITS
@@ -110,18 +95,18 @@ static drawfn glue(pl110_draw_fn_,BITS)[48] =
 #else
 
 #if ORDER == 0
-#define NAME glue(glue(lblp_, BORDER), BITS)
+#define NAME glue(lblp_, BORDER)
 #ifdef HOST_WORDS_BIGENDIAN
 #define SWAP_WORDS 1
 #endif
 #elif ORDER == 1
-#define NAME glue(glue(bbbp_, BORDER), BITS)
+#define NAME glue(bbbp_, BORDER)
 #ifndef HOST_WORDS_BIGENDIAN
 #define SWAP_WORDS 1
 #endif
 #else
 #define SWAP_PIXELS 1
-#define NAME glue(glue(lbbp_, BORDER), BITS)
+#define NAME glue(lbbp_, BORDER)
 #ifdef HOST_WORDS_BIGENDIAN
 #define SWAP_WORDS 1
 #endif
@@ -270,14 +255,14 @@ static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_
         MSB = (data & 0x1f) << 3;
         data >>= 5;
 #endif
-        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
         LSB = (data & 0x1f) << 3;
         data >>= 5;
         g = (data & 0x3f) << 2;
         data >>= 6;
         MSB = (data & 0x1f) << 3;
         data >>= 5;
-        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
 #undef MSB
 #undef LSB
         width -= 2;
@@ -307,7 +292,7 @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_
         g = (data >> 16) & 0xff;
         MSB = (data >> 8) & 0xff;
 #endif
-        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
 #undef MSB
 #undef LSB
         width--;
@@ -338,14 +323,14 @@ static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const ui
         data >>= 5;
         MSB = (data & 0x1f) << 3;
         data >>= 5;
-        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
         LSB = (data & 0x1f) << 3;
         data >>= 5;
         g = (data & 0x1f) << 3;
         data >>= 5;
         MSB = (data & 0x1f) << 3;
         data >>= 6;
-        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
 #undef MSB
 #undef LSB
         width -= 2;
@@ -376,14 +361,14 @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_
         data >>= 4;
         MSB = (data & 0xf) << 4;
         data >>= 8;
-        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
         LSB = (data & 0xf) << 4;
         data >>= 4;
         g = (data & 0xf) << 4;
         data >>= 4;
         MSB = (data & 0xf) << 4;
         data >>= 8;
-        COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
+        COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
 #undef MSB
 #undef LSB
         width -= 2;
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 11/14] pl110: move resize
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (9 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 10/14] pl100: Drop support for depths other than 32bpp Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 12/14] [wip] pl110: start using pixman Gerd Hoffmann
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Handle display resizes in the update callback.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/pl110.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index 78b146b..f788382 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -200,6 +200,13 @@ static void pl110_update_display(void *opaque)
         break;
     }
 
+    /* handle resize */
+    if (surface_width(surface) != s->cols ||
+        surface_height(surface) != s->rows) {
+        qemu_console_resize(s->con, s->cols, s->rows);
+        surface = qemu_console_surface(s->con);
+    }
+
     g_assert(surface_bits_per_pixel(surface) == 32);
     dest_width = 4 * s->cols;
     first = 0;
@@ -219,9 +226,6 @@ static void pl110_invalidate_display(void * opaque)
 {
     PL110State *s = (PL110State *)opaque;
     s->invalidate = 1;
-    if (pl110_enabled(s)) {
-        qemu_console_resize(s->con, s->cols, s->rows);
-    }
 }
 
 static void pl110_update_palette(PL110State *s, int n)
@@ -254,11 +258,6 @@ static void pl110_update_palette(PL110State *s, int n)
 
 static void pl110_resize(PL110State *s, int width, int height)
 {
-    if (width != s->cols || height != s->rows) {
-        if (pl110_enabled(s)) {
-            qemu_console_resize(s->con, width, height);
-        }
-    }
     s->cols = width;
     s->rows = height;
 }
@@ -373,9 +372,6 @@ static void pl110_write(void *opaque, hwaddr offset,
     control:
         s->cr = val;
         s->bpp = (val >> 1) & 7;
-        if (pl110_enabled(s)) {
-            qemu_console_resize(s->con, s->cols, s->rows);
-        }
         break;
     case 10: /* LCDICR */
         s->int_status &= ~val;
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 12/14] [wip] pl110: start using pixman
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (10 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 11/14] pl110: move resize Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 13/14] [wip] pl110: switch some conversions to swap+pixman mode Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 14/14] [wip] pl110: start handling paletted images via pixman Gerd Hoffmann
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Turn pl110_draw_fn into a struct, carrying both conversion function
and pixman format for a given guest framebuffer layout.  Create a
DisplaySurface backed by guest memory in case pixman can handle the
format, thereby collecting the low-hanging fruits.

A common case (linux kernel running pl111 with 16bpp, little endian
host) runs powered by pixman now.  Lot of work left to be able to kill
the template stuff completely though.

Debug printf left in for now to see what formts the guest is using.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/pl110.c          |  67 +++++++++++++++-----------
 hw/display/pl110_template.h | 111 ++++++++++++++++++++++++--------------------
 2 files changed, 101 insertions(+), 77 deletions(-)

diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index f788382..0dbc526 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -170,12 +170,13 @@ static void pl110_update_display(void *opaque)
         }
     }
 
-    if (s->cr & PL110_CR_BEBO)
-        fn = pl110_draw_fn[s->bpp + 8 + bpp_offset];
-    else if (s->cr & PL110_CR_BEPO)
-        fn = pl110_draw_fn[s->bpp + 16 + bpp_offset];
-    else
-        fn = pl110_draw_fn[s->bpp + bpp_offset];
+    if (s->cr & PL110_CR_BEBO) {
+        bpp_offset += 8 + s->bpp;
+    } else if (s->cr & PL110_CR_BEPO) {
+        bpp_offset += 16 + s->bpp;
+    } else {
+        bpp_offset += s->bpp;
+    }
 
     src_width = s->cols;
     switch (s->bpp) {
@@ -201,23 +202,39 @@ static void pl110_update_display(void *opaque)
     }
 
     /* handle resize */
-    if (surface_width(surface) != s->cols ||
+    if (s->invalidate ||
+        surface_width(surface) != s->cols ||
         surface_height(surface) != s->rows) {
-        qemu_console_resize(s->con, s->cols, s->rows);
-        surface = qemu_console_surface(s->con);
+        if (pl110_draw[bpp_offset].fmt) {
+            surface = qemu_create_displaysurface_guestmem
+                (s->cols, s->rows, pl110_draw[bpp_offset].fmt, 0, s->upbase);
+            dpy_gfx_replace_surface(s->con, surface);
+        } else {
+            qemu_console_resize(s->con, s->cols, s->rows);
+            surface = qemu_console_surface(s->con);
+        }
+        fprintf(stderr, "%s: %s memory, %dx%d, bpp_offset %d, format 0x%x\n",
+                __func__, is_buffer_shared(surface) ? "guest" : "host",
+                s->cols, s->rows, bpp_offset, surface->format);
     }
 
-    g_assert(surface_bits_per_pixel(surface) == 32);
-    dest_width = 4 * s->cols;
-    first = 0;
-    framebuffer_update_display(surface, sysbus_address_space(sbd),
-                               s->upbase, s->cols, s->rows,
-                               src_width, dest_width, 0,
-                               s->invalidate,
-                               fn, s->palette,
-                               &first, &last);
-    if (first >= 0) {
-        dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1);
+    if (is_buffer_shared(surface)) {
+        dpy_gfx_update_dirty(s->con, sysbus_address_space(sbd),
+                             s->upbase, s->invalidate);
+    } else {
+        g_assert(surface_bits_per_pixel(surface) == 32);
+        dest_width = 4 * s->cols;
+        first = 0;
+        fn = pl110_draw[bpp_offset].fn;
+        framebuffer_update_display(surface, sysbus_address_space(sbd),
+                                   s->upbase, s->cols, s->rows,
+                                   src_width, dest_width, 0,
+                                   s->invalidate,
+                                   fn, s->palette,
+                                   &first, &last);
+        if (first >= 0) {
+            dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1);
+        }
     }
     s->invalidate = 0;
 }
@@ -235,6 +252,8 @@ static void pl110_update_palette(PL110State *s, int n)
     uint32_t raw;
     unsigned int r, g, b;
 
+    g_assert(is_buffer_shared(surface) ||
+             surface_bits_per_pixel(surface) == 32);
     raw = s->raw_palette[n];
     n <<= 1;
     for (i = 0; i < 2; i++) {
@@ -245,13 +264,7 @@ static void pl110_update_palette(PL110State *s, int n)
         b = (raw & 0x1f) << 3;
         /* The I bit is ignored.  */
         raw >>= 6;
-        switch (surface_bits_per_pixel(surface)) {
-        case 32:
-            s->palette[n] = rgb_to_pixel32(r, g, b);
-            break;
-        default:
-            g_assert_not_reached();
-        }
+        s->palette[n] = rgb_to_pixel32(r, g, b);
         n++;
     }
 }
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
index 5afc64c..1eee28d 100644
--- a/hw/display/pl110_template.h
+++ b/hw/display/pl110_template.h
@@ -32,61 +32,72 @@
 #include "pl110_template.h"
 #undef BORDER
 
-static drawfn pl110_draw_fn[48] =
-{
-    pl110_draw_line1_lblp_bgr,
-    pl110_draw_line2_lblp_bgr,
-    pl110_draw_line4_lblp_bgr,
-    pl110_draw_line8_lblp_bgr,
-    pl110_draw_line16_555_lblp_bgr,
-    pl110_draw_line32_lblp_bgr,
-    pl110_draw_line16_lblp_bgr,
-    pl110_draw_line12_lblp_bgr,
+#ifdef HOST_WORDS_BIGENDIAN
+# define LEBE(le, be) (be)
+#else
+# define LEBE(le, be) (le)
+#endif
+
+static struct {
+    drawfn fn;
+    pixman_format_code_t fmt;
+} pl110_draw[48] = {
+    { .fn = pl110_draw_line1_lblp_bgr },
+    { .fn = pl110_draw_line2_lblp_bgr },
+    { .fn = pl110_draw_line4_lblp_bgr },
+    { .fn = pl110_draw_line8_lblp_bgr },
+    { .fn = pl110_draw_line16_555_lblp_bgr, .fmt = LEBE(PIXMAN_x1r5g5b5, 0) },
+    { .fn = pl110_draw_line32_lblp_bgr,     .fmt = LEBE(PIXMAN_x8r8g8b8,
+                                                        PIXMAN_b8g8r8a8)    },
+    { .fn = pl110_draw_line16_lblp_bgr,     .fmt = LEBE(PIXMAN_r5g6b5,   0) },
+    { .fn = pl110_draw_line12_lblp_bgr,     .fmt = LEBE(PIXMAN_x4r4g4b4, 0) },
 
-    pl110_draw_line1_bbbp_bgr,
-    pl110_draw_line2_bbbp_bgr,
-    pl110_draw_line4_bbbp_bgr,
-    pl110_draw_line8_bbbp_bgr,
-    pl110_draw_line16_555_bbbp_bgr,
-    pl110_draw_line32_bbbp_bgr,
-    pl110_draw_line16_bbbp_bgr,
-    pl110_draw_line12_bbbp_bgr,
+    { .fn = pl110_draw_line1_bbbp_bgr },
+    { .fn = pl110_draw_line2_bbbp_bgr },
+    { .fn = pl110_draw_line4_bbbp_bgr },
+    { .fn = pl110_draw_line8_bbbp_bgr },
+    { .fn = pl110_draw_line16_555_bbbp_bgr },
+    { .fn = pl110_draw_line32_bbbp_bgr,     .fmt = LEBE(PIXMAN_b8g8r8a8,
+                                                        PIXMAN_x8r8g8b8)    },
+    { .fn = pl110_draw_line16_bbbp_bgr },
+    { .fn = pl110_draw_line12_bbbp_bgr },
 
-    pl110_draw_line1_lbbp_bgr,
-    pl110_draw_line2_lbbp_bgr,
-    pl110_draw_line4_lbbp_bgr,
-    pl110_draw_line8_lbbp_bgr,
-    pl110_draw_line16_555_lbbp_bgr,
-    pl110_draw_line32_lbbp_bgr,
-    pl110_draw_line16_lbbp_bgr,
-    pl110_draw_line12_lbbp_bgr,
+    { .fn = pl110_draw_line1_lbbp_bgr },
+    { .fn = pl110_draw_line2_lbbp_bgr },
+    { .fn = pl110_draw_line4_lbbp_bgr },
+    { .fn = pl110_draw_line8_lbbp_bgr },
+    { .fn = pl110_draw_line16_555_lbbp_bgr, .fmt = LEBE(PIXMAN_x1r5g5b5, 0) },
+    { .fn = pl110_draw_line32_lbbp_bgr,     .fmt = LEBE(PIXMAN_x8r8g8b8,
+                                                        PIXMAN_b8g8r8a8)    },
+    { .fn = pl110_draw_line16_lbbp_bgr,     .fmt = LEBE(PIXMAN_r5g6b5,   0) },
+    { .fn = pl110_draw_line12_lbbp_bgr,     .fmt = LEBE(PIXMAN_x4r4g4b4, 0) },
 
-    pl110_draw_line1_lblp_rgb,
-    pl110_draw_line2_lblp_rgb,
-    pl110_draw_line4_lblp_rgb,
-    pl110_draw_line8_lblp_rgb,
-    pl110_draw_line16_555_lblp_rgb,
-    pl110_draw_line32_lblp_rgb,
-    pl110_draw_line16_lblp_rgb,
-    pl110_draw_line12_lblp_rgb,
+    { .fn = pl110_draw_line1_lblp_rgb },
+    { .fn = pl110_draw_line2_lblp_rgb },
+    { .fn = pl110_draw_line4_lblp_rgb },
+    { .fn = pl110_draw_line8_lblp_rgb },
+    { .fn = pl110_draw_line16_555_lblp_rgb },
+    { .fn = pl110_draw_line32_lblp_rgb },
+    { .fn = pl110_draw_line16_lblp_rgb },
+    { .fn = pl110_draw_line12_lblp_rgb },
 
-    pl110_draw_line1_bbbp_rgb,
-    pl110_draw_line2_bbbp_rgb,
-    pl110_draw_line4_bbbp_rgb,
-    pl110_draw_line8_bbbp_rgb,
-    pl110_draw_line16_555_bbbp_rgb,
-    pl110_draw_line32_bbbp_rgb,
-    pl110_draw_line16_bbbp_rgb,
-    pl110_draw_line12_bbbp_rgb,
+    { .fn = pl110_draw_line1_bbbp_rgb },
+    { .fn = pl110_draw_line2_bbbp_rgb },
+    { .fn = pl110_draw_line4_bbbp_rgb },
+    { .fn = pl110_draw_line8_bbbp_rgb },
+    { .fn = pl110_draw_line16_555_bbbp_rgb },
+    { .fn = pl110_draw_line32_bbbp_rgb },
+    { .fn = pl110_draw_line16_bbbp_rgb },
+    { .fn = pl110_draw_line12_bbbp_rgb },
 
-    pl110_draw_line1_lbbp_rgb,
-    pl110_draw_line2_lbbp_rgb,
-    pl110_draw_line4_lbbp_rgb,
-    pl110_draw_line8_lbbp_rgb,
-    pl110_draw_line16_555_lbbp_rgb,
-    pl110_draw_line32_lbbp_rgb,
-    pl110_draw_line16_lbbp_rgb,
-    pl110_draw_line12_lbbp_rgb,
+    { .fn = pl110_draw_line1_lbbp_rgb },
+    { .fn = pl110_draw_line2_lbbp_rgb },
+    { .fn = pl110_draw_line4_lbbp_rgb },
+    { .fn = pl110_draw_line8_lbbp_rgb },
+    { .fn = pl110_draw_line16_555_lbbp_rgb },
+    { .fn = pl110_draw_line32_lbbp_rgb },
+    { .fn = pl110_draw_line16_lbbp_rgb },
+    { .fn = pl110_draw_line12_lbbp_rgb },
 };
 
 #undef BITS
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 13/14] [wip] pl110: switch some conversions to swap+pixman mode
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (11 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 12/14] [wip] pl110: start using pixman Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 14/14] [wip] pl110: start handling paletted images via pixman Gerd Hoffmann
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add swapmode to struct pl110_draw_fn,
handle more framebuffer formats that way.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/pl110.c          | 26 +++++++++++++++++---------
 hw/display/pl110_template.h | 45 +++++++++++++++++++++++++++++++++++----------
 2 files changed, 52 insertions(+), 19 deletions(-)

diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index 0dbc526..6d8ae4b 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -205,7 +205,8 @@ static void pl110_update_display(void *opaque)
     if (s->invalidate ||
         surface_width(surface) != s->cols ||
         surface_height(surface) != s->rows) {
-        if (pl110_draw[bpp_offset].fmt) {
+        if (pl110_draw[bpp_offset].fmt &&
+            pl110_draw[bpp_offset].swap == FB_SWAP_NONE) {
             surface = qemu_create_displaysurface_guestmem
                 (s->cols, s->rows, pl110_draw[bpp_offset].fmt, 0, s->upbase);
             dpy_gfx_replace_surface(s->con, surface);
@@ -223,15 +224,22 @@ static void pl110_update_display(void *opaque)
                              s->upbase, s->invalidate);
     } else {
         g_assert(surface_bits_per_pixel(surface) == 32);
-        dest_width = 4 * s->cols;
         first = 0;
-        fn = pl110_draw[bpp_offset].fn;
-        framebuffer_update_display(surface, sysbus_address_space(sbd),
-                                   s->upbase, s->cols, s->rows,
-                                   src_width, dest_width, 0,
-                                   s->invalidate,
-                                   fn, s->palette,
-                                   &first, &last);
+        if (pl110_draw[bpp_offset].fmt) {
+            framebuffer_update_display_swap_pixman
+                (surface, sysbus_address_space(sbd), s->upbase,
+                 pl110_draw[bpp_offset].swap, pl110_draw[bpp_offset].fmt,
+                 s->invalidate, &first, &last);
+        } else {
+            dest_width = 4 * s->cols;
+            fn = pl110_draw[bpp_offset].fn;
+            framebuffer_update_display(surface, sysbus_address_space(sbd),
+                                       s->upbase, s->cols, s->rows,
+                                       src_width, dest_width, 0,
+                                       s->invalidate,
+                                       fn, s->palette,
+                                       &first, &last);
+        }
         if (first >= 0) {
             dpy_gfx_update(s->con, 0, first, s->cols, last - first + 1);
         }
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
index 1eee28d..d81a388 100644
--- a/hw/display/pl110_template.h
+++ b/hw/display/pl110_template.h
@@ -41,16 +41,29 @@
 static struct {
     drawfn fn;
     pixman_format_code_t fmt;
+    enum framebuffer_swapmode swap;
 } pl110_draw[48] = {
     { .fn = pl110_draw_line1_lblp_bgr },
     { .fn = pl110_draw_line2_lblp_bgr },
     { .fn = pl110_draw_line4_lblp_bgr },
     { .fn = pl110_draw_line8_lblp_bgr },
-    { .fn = pl110_draw_line16_555_lblp_bgr, .fmt = LEBE(PIXMAN_x1r5g5b5, 0) },
-    { .fn = pl110_draw_line32_lblp_bgr,     .fmt = LEBE(PIXMAN_x8r8g8b8,
-                                                        PIXMAN_b8g8r8a8)    },
-    { .fn = pl110_draw_line16_lblp_bgr,     .fmt = LEBE(PIXMAN_r5g6b5,   0) },
-    { .fn = pl110_draw_line12_lblp_bgr,     .fmt = LEBE(PIXMAN_x4r4g4b4, 0) },
+    {
+        .fn   = pl110_draw_line16_555_lblp_bgr,
+        .fmt  = PIXMAN_x1r5g5b5,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_16_BYTES),
+    },{
+        .fn   = pl110_draw_line32_lblp_bgr,
+        .fmt  = LEBE(PIXMAN_x8r8g8b8, PIXMAN_b8g8r8a8),
+        .swap = FB_SWAP_NONE
+    },{
+        .fn   = pl110_draw_line16_lblp_bgr,
+        .fmt  = PIXMAN_r5g6b5,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_16_BYTES),
+    },{
+        .fn   = pl110_draw_line12_lblp_bgr,
+        .fmt  = PIXMAN_x4r4g4b4,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_16_BYTES)
+    },
 
     { .fn = pl110_draw_line1_bbbp_bgr },
     { .fn = pl110_draw_line2_bbbp_bgr },
@@ -66,11 +79,23 @@ static struct {
     { .fn = pl110_draw_line2_lbbp_bgr },
     { .fn = pl110_draw_line4_lbbp_bgr },
     { .fn = pl110_draw_line8_lbbp_bgr },
-    { .fn = pl110_draw_line16_555_lbbp_bgr, .fmt = LEBE(PIXMAN_x1r5g5b5, 0) },
-    { .fn = pl110_draw_line32_lbbp_bgr,     .fmt = LEBE(PIXMAN_x8r8g8b8,
-                                                        PIXMAN_b8g8r8a8)    },
-    { .fn = pl110_draw_line16_lbbp_bgr,     .fmt = LEBE(PIXMAN_r5g6b5,   0) },
-    { .fn = pl110_draw_line12_lbbp_bgr,     .fmt = LEBE(PIXMAN_x4r4g4b4, 0) },
+    {
+        .fn = pl110_draw_line16_555_lbbp_bgr,
+        .fmt  = PIXMAN_x1r5g5b5,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_16_BYTES),
+    },{
+        .fn = pl110_draw_line32_lbbp_bgr,
+        .fmt  = LEBE(PIXMAN_x8r8g8b8, PIXMAN_b8g8r8a8),
+        .swap = FB_SWAP_NONE
+    },{
+        .fn = pl110_draw_line16_lbbp_bgr,
+        .fmt  = PIXMAN_r5g6b5,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_16_BYTES),
+    },{
+        .fn = pl110_draw_line12_lbbp_bgr,
+        .fmt  = PIXMAN_x4r4g4b4,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_16_BYTES)
+    },
 
     { .fn = pl110_draw_line1_lblp_rgb },
     { .fn = pl110_draw_line2_lblp_rgb },
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 14/14] [wip] pl110: start handling paletted images via pixman
  2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
                   ` (12 preceding siblings ...)
  2014-09-02  8:00 ` [Qemu-devel] [PATCH 13/14] [wip] pl110: switch some conversions to swap+pixman mode Gerd Hoffmann
@ 2014-09-02  8:00 ` Gerd Hoffmann
  13 siblings, 0 replies; 15+ messages in thread
From: Gerd Hoffmann @ 2014-09-02  8:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Supporting paletted images in pixman turned out to be pretty easy ;)
Pixman supports 1+4+8 bit/pixel, 2 bpp is missing.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/display/framebuffer.c    |  2 ++
 hw/display/framebuffer.h    |  1 +
 hw/display/pl110.c          | 20 +++++++++++++++-----
 hw/display/pl110_template.h | 18 ++++++++++++++----
 4 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/hw/display/framebuffer.c b/hw/display/framebuffer.c
index d3a2c70..27e2b66 100644
--- a/hw/display/framebuffer.c
+++ b/hw/display/framebuffer.c
@@ -164,6 +164,7 @@ void framebuffer_update_display_swap_pixman(
     hwaddr base,
     enum framebuffer_swapmode swapmode,
     pixman_format_code_t format,
+    pixman_indexed_t *palette,
     int invalidate, /* nonzero to redraw the whole image.  */
     int *first_row, /* Input and output.  */
     int *last_row /* Output only */)
@@ -214,6 +215,7 @@ void framebuffer_update_display_swap_pixman(
     src += i * src_width;
 
     linebuf = qemu_pixman_linebuf_create(format, cols);
+    pixman_image_set_indexed(linebuf, palette);
     for (; i < rows; i++) {
         dirty = memory_region_get_dirty(mem, addr, src_width,
                                         DIRTY_MEMORY_VGA);
diff --git a/hw/display/framebuffer.h b/hw/display/framebuffer.h
index 6ee6df5..40f1703 100644
--- a/hw/display/framebuffer.h
+++ b/hw/display/framebuffer.h
@@ -35,6 +35,7 @@ void framebuffer_update_display_swap_pixman(
     hwaddr base,
     enum framebuffer_swapmode,
     pixman_format_code_t format,
+    pixman_indexed_t *palette,
     int invalidate, /* nonzero to redraw the whole image.  */
     int *first_row, /* Input and output.  */
     int *last_row /* Output only */);
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index 6d8ae4b..e08614f 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -60,7 +60,7 @@ typedef struct PL110State {
     enum pl110_bppmode bpp;
     int invalidate;
     uint32_t mux_ctrl;
-    uint32_t palette[256];
+    pixman_indexed_t pixman_palette;
     uint32_t raw_palette[128];
     qemu_irq irq;
 } PL110State;
@@ -84,7 +84,7 @@ static const VMStateDescription vmstate_pl110 = {
         VMSTATE_INT32(rows, PL110State),
         VMSTATE_UINT32(bpp, PL110State),
         VMSTATE_INT32(invalidate, PL110State),
-        VMSTATE_UINT32_ARRAY(palette, PL110State, 256),
+        VMSTATE_UINT32_ARRAY(pixman_palette.rgba, PL110State, 256),
         VMSTATE_UINT32_ARRAY(raw_palette, PL110State, 128),
         VMSTATE_UINT32_V(mux_ctrl, PL110State, 2),
         VMSTATE_END_OF_LIST()
@@ -206,9 +206,19 @@ static void pl110_update_display(void *opaque)
         surface_width(surface) != s->cols ||
         surface_height(surface) != s->rows) {
         if (pl110_draw[bpp_offset].fmt &&
+#if 1
+            /*
+             * Don't expose paletted pixman images to ui for now.
+             * There are truecolor format assumtions in some places,
+             * basically everything using PixelFormat, SDL code for
+             * example.
+             */
+            PIXMAN_FORMAT_BPP(pl110_draw[bpp_offset].fmt) > 8 &&
+#endif
             pl110_draw[bpp_offset].swap == FB_SWAP_NONE) {
             surface = qemu_create_displaysurface_guestmem
                 (s->cols, s->rows, pl110_draw[bpp_offset].fmt, 0, s->upbase);
+            pixman_image_set_indexed(surface->image, &s->pixman_palette);
             dpy_gfx_replace_surface(s->con, surface);
         } else {
             qemu_console_resize(s->con, s->cols, s->rows);
@@ -229,7 +239,7 @@ static void pl110_update_display(void *opaque)
             framebuffer_update_display_swap_pixman
                 (surface, sysbus_address_space(sbd), s->upbase,
                  pl110_draw[bpp_offset].swap, pl110_draw[bpp_offset].fmt,
-                 s->invalidate, &first, &last);
+                 &s->pixman_palette, s->invalidate, &first, &last);
         } else {
             dest_width = 4 * s->cols;
             fn = pl110_draw[bpp_offset].fn;
@@ -237,7 +247,7 @@ static void pl110_update_display(void *opaque)
                                        s->upbase, s->cols, s->rows,
                                        src_width, dest_width, 0,
                                        s->invalidate,
-                                       fn, s->palette,
+                                       fn, s->pixman_palette.rgba,
                                        &first, &last);
         }
         if (first >= 0) {
@@ -272,7 +282,7 @@ static void pl110_update_palette(PL110State *s, int n)
         b = (raw & 0x1f) << 3;
         /* The I bit is ignored.  */
         raw >>= 6;
-        s->palette[n] = rgb_to_pixel32(r, g, b);
+        s->pixman_palette.rgba[n] = rgb_to_pixel32(r, g, b);
         n++;
     }
 }
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
index d81a388..f911546 100644
--- a/hw/display/pl110_template.h
+++ b/hw/display/pl110_template.h
@@ -43,11 +43,21 @@ static struct {
     pixman_format_code_t fmt;
     enum framebuffer_swapmode swap;
 } pl110_draw[48] = {
-    { .fn = pl110_draw_line1_lblp_bgr },
-    { .fn = pl110_draw_line2_lblp_bgr },
-    { .fn = pl110_draw_line4_lblp_bgr },
-    { .fn = pl110_draw_line8_lblp_bgr },
     {
+        .fn   = pl110_draw_line1_lblp_bgr,
+        .fmt  = PIXMAN_g1,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_32_BYTES),
+    },{
+        .fn   = pl110_draw_line2_lblp_bgr,
+    },{
+        .fn   = pl110_draw_line4_lblp_bgr,
+        .fmt  = PIXMAN_c4,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_32_BYTES),
+    },{
+        .fn   = pl110_draw_line8_lblp_bgr,
+        .fmt  = PIXMAN_c8,
+        .swap = LEBE(FB_SWAP_NONE, FB_SWAP_32_BYTES),
+    },{
         .fn   = pl110_draw_line16_555_lblp_bgr,
         .fmt  = PIXMAN_x1r5g5b5,
         .swap = LEBE(FB_SWAP_NONE, FB_SWAP_16_BYTES),
-- 
1.8.3.1

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

end of thread, other threads:[~2014-09-02  8:01 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-09-02  8:00 [Qemu-devel] [PATCH 00/14] console/pl110: pixman conversion continued Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 01/14] console: add qemu_pixelformat_from_pixman Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 02/14] console: add qemu_default_pixman_format Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 03/14] console: reimplement qemu_default_pixelformat Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 04/14] console: stop using PixelFormat Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 05/14] console: add qemu_create_displaysurface_guestmem Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 06/14] console: add dpy_gfx_update_dirty Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 07/14] console: add qemu_pixman_linebuf_copy Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 08/14] console: Remove unused QEMU_BIG_ENDIAN_FLAG Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 09/14] pl110: add framebuffer_update_display_swap_pixman Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 10/14] pl100: Drop support for depths other than 32bpp Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 11/14] pl110: move resize Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 12/14] [wip] pl110: start using pixman Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 13/14] [wip] pl110: switch some conversions to swap+pixman mode Gerd Hoffmann
2014-09-02  8:00 ` [Qemu-devel] [PATCH 14/14] [wip] pl110: start handling paletted images via pixman Gerd Hoffmann

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