From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=49782 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OOBdB-0001fc-UM for qemu-devel@nongnu.org; Mon, 14 Jun 2010 11:31:23 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OOBdA-0008Q2-C3 for qemu-devel@nongnu.org; Mon, 14 Jun 2010 11:31:21 -0400 Received: from mail-iw0-f173.google.com ([209.85.214.173]:54341) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OOBdA-0008Pv-7c for qemu-devel@nongnu.org; Mon, 14 Jun 2010 11:31:20 -0400 Received: by iwn10 with SMTP id 10so4291822iwn.4 for ; Mon, 14 Jun 2010 08:31:19 -0700 (PDT) Message-ID: <4C164B45.8000102@codemonkey.ws> Date: Mon, 14 Jun 2010 10:31:17 -0500 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [RfC PATCH] add pflib: PixelFormat conversion library. References: <1276529156-19055-1-git-send-email-kraxel@redhat.com> In-Reply-To: <1276529156-19055-1-git-send-email-kraxel@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Gerd Hoffmann Cc: qemu-devel@nongnu.org On 06/14/2010 10:25 AM, Gerd Hoffmann wrote: > Signed-off-by: Gerd Hoffmann > --- > Makefile.objs | 1 + > pflib.c | 204 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > pflib.h | 6 ++ > 3 files changed, 211 insertions(+), 0 deletions(-) > create mode 100644 pflib.c > create mode 100644 pflib.h > > diff --git a/Makefile.objs b/Makefile.objs > index 2dad0f9..6201675 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -83,6 +83,7 @@ common-obj-y += qemu-char.o savevm.o #aio.o > common-obj-y += msmouse.o ps2.o > common-obj-y += qdev.o qdev-properties.o > common-obj-y += block-migration.o > +common-obj-y += pflib.o > > common-obj-$(CONFIG_BRLAPI) += baum.o > common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o > diff --git a/pflib.c b/pflib.c > new file mode 100644 > index 0000000..1c04378 > --- /dev/null > +++ b/pflib.c > Good idea but needs copyright/license. Regards, Anthony Liguori > @@ -0,0 +1,204 @@ > +#include "qemu-common.h" > +#include "console.h" > +#include "pflib.h" > + > +typedef struct QemuPixel QemuPixel; > + > +typedef void (*pf_convert)(QemuPfConv *conv, > + void *dst, void *src, uint32_t cnt); > +typedef void (*pf_convert_from)(PixelFormat *pf, > + QemuPixel *dst, void *src, uint32_t cnt); > +typedef void (*pf_convert_to)(PixelFormat *pf, > + void *dst, QemuPixel *src, uint32_t cnt); > + > +struct QemuPfConv { > + pf_convert convert; > + PixelFormat src; > + PixelFormat dst; > + > + /* for copy_generic() */ > + pf_convert_from conv_from; > + pf_convert_to conv_to; > + QemuPixel *conv_buf; > + uint32_t conv_cnt; > +}; > + > +struct QemuPixel { > + uint8_t red; > + uint8_t green; > + uint8_t blue; > + uint8_t alpha; > +}; > + > +/* ----------------------------------------------------------------------- */ > +/* PixelFormat -> QemuPixel conversions */ > + > +static void conv_16_to_pixel(PixelFormat *pf, > + QemuPixel *dst, void *src, uint32_t cnt) > +{ > + uint16_t *src16 = src; > + > + while (cnt> 0) { > + dst->red = ((*src16& pf->rmask)>> pf->rshift)<< (8 - pf->rbits); > + dst->green = ((*src16& pf->gmask)>> pf->gshift)<< (8 - pf->gbits); > + dst->blue = ((*src16& pf->bmask)>> pf->bshift)<< (8 - pf->bbits); > + dst->alpha = ((*src16& pf->amask)>> pf->ashift)<< (8 - pf->abits); > + dst++, src16++, cnt--; > + } > +} > + > +/* assumes pf->{r,g,b,a}bits == 8 */ > +static void conv_32_to_pixel_fast(PixelFormat *pf, > + QemuPixel *dst, void *src, uint32_t cnt) > +{ > + uint32_t *src32 = src; > + > + while (cnt> 0) { > + dst->red = (*src32& pf->rmask)>> pf->rshift; > + dst->green = (*src32& pf->gmask)>> pf->gshift; > + dst->blue = (*src32& pf->bmask)>> pf->bshift; > + dst->alpha = (*src32& pf->amask)>> pf->ashift; > + dst++, src32++, cnt--; > + } > +} > + > +static void conv_32_to_pixel_generic(PixelFormat *pf, > + QemuPixel *dst, void *src, uint32_t cnt) > +{ > + uint32_t *src32 = src; > + > + while (cnt> 0) { > + if (pf->rbits< 8) { > + dst->red = ((*src32& pf->rmask)>> pf->rshift)<< (8 - pf->rbits); > + } else { > + dst->red = ((*src32& pf->rmask)>> pf->rshift)>> (pf->rbits - 8); > + } > + if (pf->gbits< 8) { > + dst->green = ((*src32& pf->gmask)>> pf->gshift)<< (8 - pf->gbits); > + } else { > + dst->green = ((*src32& pf->gmask)>> pf->gshift)>> (pf->gbits - 8); > + } > + if (pf->bbits< 8) { > + dst->blue = ((*src32& pf->bmask)>> pf->bshift)<< (8 - pf->bbits); > + } else { > + dst->blue = ((*src32& pf->bmask)>> pf->bshift)>> (pf->bbits - 8); > + } > + if (pf->abits< 8) { > + dst->alpha = ((*src32& pf->amask)>> pf->ashift)<< (8 - pf->abits); > + } else { > + dst->alpha = ((*src32& pf->amask)>> pf->ashift)>> (pf->abits - 8); > + } > + dst++, src32++, cnt--; > + } > +} > + > +/* ----------------------------------------------------------------------- */ > +/* QemuPixel -> PixelFormat conversions */ > + > +static void conv_pixel_to_16(PixelFormat *pf, > + void *dst, QemuPixel *src, uint32_t cnt) > +{ > + uint16_t *dst16 = dst; > + > + while (cnt> 0) { > + *dst16 = ((uint16_t)src->red>> (8 - pf->rbits))<< pf->rshift; > + *dst16 |= ((uint16_t)src->green>> (8 - pf->gbits))<< pf->gshift; > + *dst16 |= ((uint16_t)src->blue>> (8 - pf->bbits))<< pf->bshift; > + *dst16 |= ((uint16_t)src->alpha>> (8 - pf->abits))<< pf->ashift; > + dst16++, src++, cnt--; > + } > +} > + > +static void conv_pixel_to_32(PixelFormat *pf, > + void *dst, QemuPixel *src, uint32_t cnt) > +{ > + uint32_t *dst32 = dst; > + > + while (cnt> 0) { > + *dst32 = ((uint32_t)src->red>> (8 - pf->rbits))<< pf->rshift; > + *dst32 |= ((uint32_t)src->green>> (8 - pf->gbits))<< pf->gshift; > + *dst32 |= ((uint32_t)src->blue>> (8 - pf->bbits))<< pf->bshift; > + *dst32 |= ((uint32_t)src->alpha>> (8 - pf->abits))<< pf->ashift; > + dst32++, src++, cnt--; > + } > +} > + > +/* ----------------------------------------------------------------------- */ > +/* PixelFormat -> PixelFormat conversions */ > + > +static void convert_copy(QemuPfConv *conv, void *dst, void *src, uint32_t cnt) > +{ > + uint32_t bytes = cnt * conv->src.bytes_per_pixel; > + memcpy(dst, src, bytes); > +} > + > +static void convert_generic(QemuPfConv *conv, void *dst, void *src, uint32_t cnt) > +{ > + if (conv->conv_cnt< cnt) { > + conv->conv_cnt = cnt; > + conv->conv_buf = qemu_realloc(conv->conv_buf, sizeof(QemuPixel) * conv->conv_cnt); > + } > + conv->conv_from(&conv->src, conv->conv_buf, src, cnt); > + conv->conv_to(&conv->dst, dst, conv->conv_buf, cnt); > +} > + > +/* ----------------------------------------------------------------------- */ > +/* public interface */ > + > +QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src) > +{ > + QemuPfConv *conv = qemu_mallocz(sizeof(QemuPfConv)); > + > + conv->src = *src; > + conv->dst = *dst; > + > + if (memcmp(&conv->src,&conv->dst, sizeof(PixelFormat)) == 0) { > + /* formats identical, can simply copy */ > + conv->convert = convert_copy; > + } else { > + /* generic two-step conversion: src -> QemuPixel -> dst */ > + switch (conv->src.bytes_per_pixel) { > + case 2: > + conv->conv_from = conv_16_to_pixel; > + break; > + case 4: > + if (conv->src.rbits == 8&& conv->src.gbits == 8&& conv->src.bbits == 8) { > + conv->conv_from = conv_32_to_pixel_fast; > + } else { > + conv->conv_from = conv_32_to_pixel_generic; > + } > + break; > + default: > + goto err; > + } > + switch (conv->dst.bytes_per_pixel) { > + case 2: > + conv->conv_to = conv_pixel_to_16; > + break; > + case 4: > + conv->conv_to = conv_pixel_to_32; > + break; > + default: > + goto err; > + } > + conv->convert = convert_generic; > + } > + return conv; > + > +err: > + qemu_free(conv); > + return NULL; > +} > + > +void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt) > +{ > + conv->convert(conv, dst, src, cnt); > +} > + > +void qemu_pf_conv_put(QemuPfConv *conv) > +{ > + if (conv) { > + qemu_free(conv->conv_buf); > + qemu_free(conv); > + } > +} > diff --git a/pflib.h b/pflib.h > new file mode 100644 > index 0000000..8d73fdd > --- /dev/null > +++ b/pflib.h > @@ -0,0 +1,6 @@ > +/* public */ > +typedef struct QemuPfConv QemuPfConv; > + > +QemuPfConv *qemu_pf_conv_get(PixelFormat *dst, PixelFormat *src); > +void qemu_pf_conv_run(QemuPfConv *conv, void *dst, void *src, uint32_t cnt); > +void qemu_pf_conv_put(QemuPfConv *conv); >