All of lore.kernel.org
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: Gerd Hoffmann <kraxel@redhat.com>, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 7/9] fbdev: move to pixman
Date: Tue, 18 Sep 2012 16:08:09 -0500	[thread overview]
Message-ID: <87sjaf6nuu.fsf@codemonkey.ws> (raw)
In-Reply-To: <87txuvqh1u.fsf@codemonkey.ws>

Anthony Liguori <anthony@codemonkey.ws> writes:

> Gerd Hoffmann <kraxel@redhat.com> writes:
>
>> Stop reinventing the wheel.  Use the pixman library for raster ops.
>>
>> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>
> Why not cairo?  I already have a cairo backend that uses GTK that
> supports scaling.  That would be a good opportunity for sharing even
> more code.

Nevermind, I see that cairo uses pixman under the covers...

Regards,

Anthony Liguori

>
> Regards,
>
> Anthony Liguori
>
>> ---
>>  configure  |   12 ++++
>>  ui/fbdev.c |  172 +++++++++++++++++++++++++++++++++++------------------------
>>  2 files changed, 114 insertions(+), 70 deletions(-)
>>
>> diff --git a/configure b/configure
>> index c4ba338..d10ff78 100755
>> --- a/configure
>> +++ b/configure
>> @@ -148,6 +148,7 @@ docs=""
>>  fdt=""
>>  nptl=""
>>  sdl=""
>> +pixman=""
>>  fbdev="no"
>>  virtfs=""
>>  vnc="yes"
>> @@ -2153,6 +2154,17 @@ else
>>      exit 1
>>  fi
>>  
>> +if $pkg_config pixman-1 > /dev/null 2>&1
>> +then
>> +    pixman="yes"
>> +    pixman_cflags=`$pkg_config --cflags pixman-1 2>/dev/null`
>> +    pixman_libs=`$pkg_config --libs pixman-1 2>/dev/null`
>> +    QEMU_CFLAGS="$QEMU_CFLAGS $pixman_cflags"
>> +    libs_softmmu="$libs_softmmu $pixman_libs"
>> +else
>> +    fbdev="no"
>> +fi
>> +
>>  ##########################################
>>  # libcap probe
>>  
>> diff --git a/ui/fbdev.c b/ui/fbdev.c
>> index 40fc7d4..4cb4d1d 100644
>> --- a/ui/fbdev.c
>> +++ b/ui/fbdev.c
>> @@ -23,11 +23,12 @@
>>  #include <linux/vt.h>
>>  #include <linux/fb.h>
>>  
>> +#include <pixman.h>
>> +
>>  #include "qemu-common.h"
>>  #include "console.h"
>>  #include "keymaps.h"
>>  #include "sysemu.h"
>> -#include "pflib.h"
>>  
>>  /*
>>   * must be last so we get the linux input layer
>> @@ -70,19 +71,82 @@ static bool                       key_down[KEY_CNT];
>>  #define FB_ACQ_REQ   3
>>  static int fb_switch_state;
>>  
>> -/* qdev windup */
>> +/* qemu windup */
>>  static DisplayChangeListener      *dcl;
>> -static QemuPfConv                 *conv;
>> -static PixelFormat                fbpf;
>>  static int                        resize_screen;
>>  static int                        redraw_screen;
>>  static int                        cx, cy, cw, ch;
>>  static Notifier                   exit_notifier;
>> +static pixman_image_t             *surface;
>> +static pixman_image_t             *framebuffer;
>> +static pixman_transform_t         transform;
>> +static pixman_region16_t          dirty;
>>  
>>  /* fwd decls */
>>  static int fbdev_activate_vt(int tty, int vtno, bool wait);
>>  
>>  /* -------------------------------------------------------------------- */
>> +/* pixman helpers                                                       */
>> +
>> +static int pixman_shifts_to_type(int rshift, int gshift, int bshift)
>> +{
>> +    int type = PIXMAN_TYPE_OTHER;
>> +
>> +    if (rshift > gshift && gshift > bshift) {
>> +        if (bshift == 0) {
>> +            type = PIXMAN_TYPE_ARGB;
>> +        } else {
>> +#if PIXMAN_VERSION >= PIXMAN_VERSION_ENCODE(0, 21, 8)
>> +            type = PIXMAN_TYPE_RGBA;
>> +#endif
>> +        }
>> +    } else if (rshift < gshift && gshift < bshift) {
>> +        if (rshift == 0) {
>> +            type = PIXMAN_TYPE_ABGR;
>> +        } else {
>> +            type = PIXMAN_TYPE_BGRA;
>> +        }
>> +    }
>> +    return type;
>> +}
>> +
>> +static pixman_image_t *pixman_from_displaystate(DisplayState *ds)
>> +{
>> +    PixelFormat *pf = &ds->surface->pf;
>> +    pixman_format_code_t format;
>> +    pixman_image_t *image;
>> +    int type;
>> +
>> +    type = pixman_shifts_to_type(pf->rshift, pf->gshift, pf->bshift);
>> +    format = PIXMAN_FORMAT(pf->bits_per_pixel, type,
>> +                           pf->abits, pf->rbits, pf->gbits, pf->bbits);
>> +    image = pixman_image_create_bits(format, ds_get_width(ds),
>> +                                     ds_get_height(ds),
>> +                                     (void *)ds_get_data(ds),
>> +                                     ds_get_linesize(ds));
>> +    return image;
>> +}
>> +
>> +static pixman_image_t *pixman_from_framebuffer(void)
>> +{
>> +    pixman_format_code_t format;
>> +    pixman_image_t *image;
>> +    int type;
>> +
>> +    type = pixman_shifts_to_type(fb_var.red.offset,
>> +                                 fb_var.green.offset,
>> +                                 fb_var.blue.offset);
>> +    format = PIXMAN_FORMAT(fb_var.bits_per_pixel, type,
>> +                           fb_var.transp.length,
>> +                           fb_var.red.length,
>> +                           fb_var.green.length,
>> +                           fb_var.blue.length);
>> +    image = pixman_image_create_bits(format, fb_var.xres, fb_var.yres,
>> +                                     (void *)fb_mem, fb_fix.line_length);
>> +    return image;
>> +}
>> +
>> +/* -------------------------------------------------------------------- */
>>  /* mouse                                                                */
>>  
>>  static void read_mouse(void *opaque)
>> @@ -529,6 +593,17 @@ static void fbdev_cleanup(void)
>>  {
>>      trace_fbdev_cleanup();
>>  
>> +    /* release pixman stuff */
>> +    pixman_region_fini(&dirty);
>> +    if (framebuffer) {
>> +        pixman_image_unref(framebuffer);
>> +        framebuffer = NULL;
>> +    }
>> +    if (surface) {
>> +        pixman_image_unref(surface);
>> +        surface = NULL;
>> +    }
>> +
>>      /* restore console */
>>      if (fb_mem != NULL) {
>>          munmap(fb_mem, fb_fix.smem_len+fb_mem_offset);
>> @@ -681,36 +756,8 @@ static int fbdev_init(const char *device)
>>      start_mediumraw(tty);
>>      qemu_set_fd_handler(tty, read_mediumraw, NULL, NULL);
>>  
>> -    /* create PixelFormat from fbdev structs */
>> -    fbpf.bits_per_pixel  = fb_var.bits_per_pixel;
>> -    fbpf.bytes_per_pixel = (fb_var.bits_per_pixel+7)/8;
>> -    fbpf.depth           = fb_var.bits_per_pixel == 32
>> -        ? 24 : fb_var.bits_per_pixel;
>> -    fbpf.rshift          = fb_var.red.offset;
>> -    fbpf.rbits           = fb_var.red.length;
>> -    fbpf.gshift          = fb_var.green.offset;
>> -    fbpf.gbits           = fb_var.green.length;
>> -    fbpf.bshift          = fb_var.blue.offset;
>> -    fbpf.bbits           = fb_var.blue.length;
>> -    fbpf.ashift          = fb_var.transp.offset;
>> -    fbpf.abits           = fb_var.transp.length;
>> -
>> -    if (fbpf.rbits) {
>> -        fbpf.rmax   = (1 << fbpf.rbits) - 1;
>> -        fbpf.rmask  = fbpf.rmax << fbpf.rshift;
>> -    }
>> -    if (fbpf.gbits) {
>> -        fbpf.gmax   = (1 << fbpf.gbits) - 1;
>> -        fbpf.gmask  = fbpf.gmax << fbpf.gshift;
>> -    }
>> -    if (fbpf.bbits) {
>> -        fbpf.bmax   = (1 << fbpf.bbits) - 1;
>> -        fbpf.bmask  = fbpf.bmax << fbpf.bshift;
>> -    }
>> -    if (fbpf.abits) {
>> -        fbpf.amax   = (1 << fbpf.abits) - 1;
>> -        fbpf.amask  = fbpf.amax << fbpf.ashift;
>> -    }
>> +    framebuffer = pixman_from_framebuffer();
>> +    pixman_region_init(&dirty);
>>      return 0;
>>  
>>  err_early:
>> @@ -818,36 +865,15 @@ static int fbdev_switch_init(void)
>>  /* -------------------------------------------------------------------- */
>>  /* rendering                                                            */
>>  
>> -static void fbdev_render(DisplayState *ds, int x, int y, int w, int h)
>> +static void fbdev_render(DisplayState *ds)
>>  {
>> -    uint8_t *dst;
>> -    uint8_t *src;
>> -    int line;
>> -
>> -    if (!conv) {
>> -        return;
>> -    }
>> -
>> -    src = ds_get_data(ds) + y * ds_get_linesize(ds)
>> -        + x * ds_get_bytes_per_pixel(ds);
>> -    dst = fb_mem + y * fb_fix.line_length
>> -        + x * fbpf.bytes_per_pixel;
>> -
>> -    dst += cy * fb_fix.line_length;
>> -    dst += cx * fbpf.bytes_per_pixel;
>> +    assert(surface);
>>  
>> -    if (h > fb_var.yres - y) {
>> -        h = fb_var.yres - y;
>> -    }
>> -    if (w > fb_var.xres - x) {
>> -        w = fb_var.xres - x;
>> -    }
>> -
>> -    for (line = y; line < y+h; line++) {
>> -        qemu_pf_conv_run(conv, dst, src, w);
>> -        dst += fb_fix.line_length;
>> -        src += ds_get_linesize(ds);
>> -    }
>> +    pixman_image_set_clip_region(surface, &dirty);
>> +    pixman_image_composite(PIXMAN_OP_SRC, surface, NULL, framebuffer,
>> +                           0, 0, 0, 0, 0, 0, fb_var.xres, fb_var.yres);
>> +    pixman_region_fini(&dirty);
>> +    pixman_region_init(&dirty);
>>  }
>>  
>>  /* -------------------------------------------------------------------- */
>> @@ -871,14 +897,16 @@ static void fbdev_update(DisplayState *ds, int x, int y, int w, int h)
>>          if (ds_get_height(ds) < fb_var.yres) {
>>              cy = (fb_var.yres - ds_get_height(ds)) / 2;
>>          }
>> -
>> -        if (conv) {
>> -            qemu_pf_conv_put(conv);
>> -        }
>> -        conv = qemu_pf_conv_get(&fbpf, &ds->surface->pf);
>> -        if (conv == NULL) {
>> -            fprintf(stderr, "fbdev: unsupported PixelFormat conversion\n");
>> +        if (surface) {
>> +            pixman_image_unref(surface);
>>          }
>> +        surface = pixman_from_displaystate(ds);
>> +
>> +        pixman_transform_init_identity(&transform);
>> +        pixman_transform_translate(&transform, NULL,
>> +                                   pixman_int_to_fixed(-cx),
>> +                                   pixman_int_to_fixed(-cy));
>> +        pixman_image_set_transform(surface, &transform);
>>      }
>>  
>>      if (redraw_screen) {
>> @@ -888,7 +916,7 @@ static void fbdev_update(DisplayState *ds, int x, int y, int w, int h)
>>          x = 0; y = 0; w = ds_get_width(ds); h = ds_get_height(ds);
>>      }
>>  
>> -    fbdev_render(ds, x, y, w, h);
>> +    pixman_region_union_rect(&dirty, &dirty, x, y, w, h);
>>  }
>>  
>>  static void fbdev_resize(DisplayState *ds)
>> @@ -924,6 +952,10 @@ static void fbdev_refresh(DisplayState *ds)
>>      if (redraw_screen) {
>>          fbdev_update(ds, 0, 0, 0, 0);
>>      }
>> +
>> +    if (pixman_region_not_empty(&dirty)) {
>> +        fbdev_render(ds);
>> +    }
>>  }
>>  
>>  static void fbdev_exit_notifier(Notifier *notifier, void *data)
>> -- 
>> 1.7.1

  reply	other threads:[~2012-09-18 21:08 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-09-18  7:17 [Qemu-devel] [PULL 0/9] linux framebuffer display driver Gerd Hoffmann
2012-09-18  7:17 ` [Qemu-devel] [PATCH 1/9] QLIST-ify display change listeners Gerd Hoffmann
2012-09-18  7:17 ` [Qemu-devel] [PATCH 2/9] add unregister_displaychangelistener Gerd Hoffmann
2012-09-18 10:54   ` Stefano Stabellini
2012-09-18  7:17 ` [Qemu-devel] [PATCH 3/9] move set_mouse + cursor_define callbacks Gerd Hoffmann
2012-09-18 14:10   ` Stefano Stabellini
2012-09-18 16:31     ` Gerd Hoffmann
2012-09-18 16:44       ` Stefano Stabellini
2012-09-18  7:17 ` [Qemu-devel] [PATCH 4/9] fbdev: add linux framebuffer display driver Gerd Hoffmann
2012-09-18 15:01   ` Stefano Stabellini
2012-09-19  5:19     ` Gerd Hoffmann
2012-09-19 18:37   ` Blue Swirl
2012-09-18  7:17 ` [Qemu-devel] [PATCH 5/9] fbdev: add monitor command to enable/disable Gerd Hoffmann
2012-09-18 12:47   ` Luiz Capitulino
2012-09-18  7:17 ` [Qemu-devel] [PATCH 6/9] fbdev: make configurable at compile time Gerd Hoffmann
2012-09-18  7:17 ` [Qemu-devel] [PATCH 7/9] fbdev: move to pixman Gerd Hoffmann
2012-09-18 15:01   ` Stefano Stabellini
2012-09-19  5:51     ` Gerd Hoffmann
2012-09-18 19:14   ` Anthony Liguori
2012-09-18 21:08     ` Anthony Liguori [this message]
2012-11-26 18:42     ` Alexander Graf
2012-11-26 20:01       ` Gerd Hoffmann
2012-11-26 20:05         ` Alexander Graf
2012-09-18 20:30   ` Søren Sandmann
2012-09-19  5:56     ` Gerd Hoffmann
2012-09-18  7:17 ` [Qemu-devel] [PATCH 8/9] fbdev: add mouse pointer support Gerd Hoffmann
2012-09-18  7:17 ` [Qemu-devel] [PATCH 9/9] fbdev: add display scaling support Gerd Hoffmann
2012-09-18 15:02   ` Stefano Stabellini
2012-09-19  5:52     ` Gerd Hoffmann
  -- strict thread matches above, loose matches on Subject: below --
2012-09-19 11:15 [Qemu-devel] [PATCH v4 0/9] linux framebuffer display driver Gerd Hoffmann
2012-09-19 11:15 ` [Qemu-devel] [PATCH 7/9] fbdev: move to pixman Gerd Hoffmann
2012-09-19 18:10   ` Stefano Stabellini
2012-09-20  6:16     ` Gerd Hoffmann
2012-09-20 11:33       ` Stefano Stabellini
2012-09-20 13:51         ` Gerd Hoffmann
2012-09-20 15:20           ` Stefano Stabellini
2012-09-20 15:27             ` Gerd Hoffmann
2012-09-20 15:28               ` Stefano Stabellini
2012-09-20 15:33                 ` Stefano Stabellini
2012-09-21  5:40                   ` Gerd Hoffmann
2012-09-21 10:48                     ` Stefano Stabellini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87sjaf6nuu.fsf@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=kraxel@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.