[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 7/9] fbdev: move to pixman
From: |
Anthony Liguori |
Subject: |
Re: [Qemu-devel] [PATCH 7/9] fbdev: move to pixman |
Date: |
Tue, 18 Sep 2012 16:08:09 -0500 |
User-agent: |
Notmuch/0.13.2+93~ged93d79 (http://notmuchmail.org) Emacs/23.3.1 (x86_64-pc-linux-gnu) |
Anthony Liguori <address@hidden> writes:
> Gerd Hoffmann <address@hidden> writes:
>
>> Stop reinventing the wheel. Use the pixman library for raster ops.
>>
>> Signed-off-by: Gerd Hoffmann <address@hidden>
>
> 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
- Re: [Qemu-devel] [PATCH 5/9] fbdev: add monitor command to enable/disable, (continued)
- [Qemu-devel] [PATCH 6/9] fbdev: make configurable at compile time., Gerd Hoffmann, 2012/09/18
- [Qemu-devel] [PATCH 8/9] fbdev: add mouse pointer support, Gerd Hoffmann, 2012/09/18
- [Qemu-devel] [PATCH 9/9] fbdev: add display scaling support, Gerd Hoffmann, 2012/09/18
- [Qemu-devel] [PATCH 7/9] fbdev: move to pixman, Gerd Hoffmann, 2012/09/18
- [Qemu-devel] [PATCH 4/9] fbdev: add linux framebuffer display driver., Gerd Hoffmann, 2012/09/18