From: Gerd Hoffmann <kraxel@redhat.com>
To: qemu-devel@nongnu.org
Cc: Gerd Hoffmann <kraxel@redhat.com>
Subject: [Qemu-devel] [PATCH 7/9] fbdev: move to pixman
Date: Tue, 18 Sep 2012 09:17:12 +0200 [thread overview]
Message-ID: <1347952634-12286-8-git-send-email-kraxel@redhat.com> (raw)
In-Reply-To: <1347952634-12286-1-git-send-email-kraxel@redhat.com>
Stop reinventing the wheel. Use the pixman library for raster ops.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
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
next prev parent reply other threads:[~2012-09-18 7:17 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 ` Gerd Hoffmann [this message]
2012-09-18 15:01 ` [Qemu-devel] [PATCH 7/9] fbdev: move to pixman Stefano Stabellini
2012-09-19 5:51 ` Gerd Hoffmann
2012-09-18 19:14 ` Anthony Liguori
2012-09-18 21:08 ` Anthony Liguori
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=1347952634-12286-8-git-send-email-kraxel@redhat.com \
--to=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 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).