diff --git a/Makefile.objs b/Makefile.objs index 9eca179903d242851f38b68c7f6490c70b50a58e..acca2854d1892ef505312b7a0dc213def6c0b850 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -65,6 +65,7 @@ common-obj-y = $(block-obj-y) blockdev.o blockdev-nbd.o block/ common-obj-y += net.o net/ common-obj-y += qom/ common-obj-y += readline.o console.o cursor.o +common-obj-y += qemu-pixman.o common-obj-y += $(oslib-obj-y) common-obj-$(CONFIG_WIN32) += os-win32.o common-obj-$(CONFIG_POSIX) += os-posix.o diff --git a/qemu-pixman.c b/qemu-pixman.c new file mode 100644 index 0000000000000000000000000000000000000000..7547ed74c11769b6c3944065588becfa7c1a761d --- /dev/null +++ b/qemu-pixman.c @@ -0,0 +1,60 @@ +#include "qemu-pixman.h" + +int qemu_pixman_get_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; +} + +pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf) +{ + pixman_format_code_t format; + int type; + + type = qemu_pixman_get_type(pf->rshift, pf->gshift, pf->bshift); + format = PIXMAN_FORMAT(pf->bits_per_pixel, type, + pf->abits, pf->rbits, pf->gbits, pf->bbits); + if (!pixman_format_supported_source(format)) { + return 0; + } + return format; +} + +pixman_image_t *qemu_pixman_linebuf_create(pixman_format_code_t format, + int width) +{ + pixman_image_t *image = pixman_image_create_bits(format, width, 1, NULL, 0); + assert(image != NULL); + return image; +} + +void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb, + int width, int y) +{ + pixman_image_composite(PIXMAN_OP_SRC, fb, NULL, linebuf, + 0, y, 0, 0, 0, 0, width, 1); +} + +void qemu_pixman_image_unref(pixman_image_t *image) +{ + if (image == NULL) { + return; + } + pixman_image_unref(image); +} diff --git a/qemu-pixman.h b/qemu-pixman.h new file mode 100644 index 0000000000000000000000000000000000000000..7652c412778dbdc3d27d11adfb7afd22e6f2f46a --- /dev/null +++ b/qemu-pixman.h @@ -0,0 +1,32 @@ +#ifndef QEMU_PIXMAN_H +#define QEMU_PIXMAN_H + +#include + +#include "console.h" + +/* + * pixman image formats are defined to be native endian, + * that means host byte order on qemu. So we go define + * fixed formats here for cases where it is needed, like + * feeding libjpeg / libpng and writing screenshots. + */ + +#ifdef HOST_WORDS_BIGENDIAN +# define PIXMAN_BE_r8g8b8 PIXMAN_r8g8b8 +#else +# define PIXMAN_BE_r8g8b8 PIXMAN_b8g8r8 +#endif + +/* -------------------------------------------------------------------- */ + +int qemu_pixman_get_type(int rshift, int gshift, int bshift); +pixman_format_code_t qemu_pixman_get_format(PixelFormat *pf); + +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 y); +void qemu_pixman_image_unref(pixman_image_t *image); + +#endif /* QEMU_PIXMAN_H */