added updated 16bpp patch that handles 555 BRG and does bit of inlining

git-svn-id: https://svn.o-hand.com/repos/poky/trunk@1595 311d38ba-8fff-0310-9ca6-ca027cbcb966
This commit is contained in:
Tomas Frydrych 2007-05-04 14:56:43 +00:00
parent 85d984ea18
commit 0efc0dfc20
1 changed files with 258 additions and 0 deletions

View File

@ -0,0 +1,258 @@
--- libmatchbox/libmb/mbpixbuf.c.orig 2007-05-04 14:41:55.000000000 +0100
+++ libmatchbox/libmb/mbpixbuf.c 2007-05-04 14:41:55.000000000 +0100
@@ -710,46 +710,19 @@
return colnum;
}
-
-static unsigned long
-mb_pixbuf_get_pixel(MBPixbuf *pb, int r, int g, int b, int a)
+/*
+ * Split the mb_pixbuf_get_pixel() function into several specialized
+ * functions which we will inline; this allows us to optimize
+ * mb_pixbuf_img_render_to_drawable_with_gc () by taking some of the
+ * decision taking outside of the double loop
+ */
+
+/*
+ * Get pixel value for rgb values and pixel depth <= 8
+ */
+static inline unsigned long
+mb_pixbuf_get_pixel_le8_rgb (MBPixbuf *pb, int r, int g, int b)
{
- if (pb->depth > 8)
- {
- switch (pb->depth)
- {
- case 15:
- return ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
- case 16:
- return ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
- case 24:
- case 32:
- switch (pb->byte_order)
- {
- case BYTE_ORD_24_RGB:
- return ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
- case BYTE_ORD_24_RBG:
- return ((r & 0xff) << 16) | ((b & 0xff) << 8) | (g & 0xff);
- case BYTE_ORD_24_BRG:
- return ((b & 0xff) << 16) | ((r & 0xff) << 8) | (g & 0xff);
- case BYTE_ORD_24_BGR:
- return ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff);
- case BYTE_ORD_24_GRB:
- return ((g & 0xff) << 16) | ((r & 0xff) << 8) | (b & 0xff);
- case BYTE_ORD_24_GBR:
- return ((g & 0xff) << 16) | ((b & 0xff) << 8) | (r & 0xff);
- case BYTE_ORD_32_ARGB:
- return (a << 24) | (r << 16) | (g << 8) | b;
- default:
- return 0;
- }
- default:
- return 0;
- }
- return 0;
- }
-
- /* pb->depth <= 8 */
switch(pb->vis->class)
{
case PseudoColor:
@@ -794,6 +767,111 @@
return 0;
}
+/*
+ * Get pixel value from a pointer to 16bbp value for pixel depth <= 8
+ * and advance the pointer
+ */
+static inline unsigned long
+mb_pixbuf_get_pixel_le8_16bpp_advance (MBPixbuf *pb, unsigned char ** p)
+{
+ unsigned short s = SHORT_FROM_2BYTES(*p);
+ int r, b, g;
+
+ r = (s & 0xf800) >> 8;
+ g = (s & 0x07e0) >> 3;
+ b = (s & 0x001f) << 3;
+
+ *p += 2;
+
+ return mb_pixbuf_get_pixel_le8_rgb (pb, r, g, b);
+}
+
+/*
+ * Get pixel value for rgba values and pixel depth > 8
+ *
+ */
+static inline unsigned long
+mb_pixbuf_get_pixel_gt8_rgba (MBPixbuf *pb, int r, int g, int b, int a)
+{
+ switch (pb->depth)
+ {
+ case 15:
+ switch (pb->byte_order)
+ {
+ case BYTE_ORD_24_RGB:
+ return ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
+ case BYTE_ORD_24_BGR:
+ return ((b & 0xf8) << 7) | ((g & 0xf8) << 2) | ((r & 0xf8) >> 3);
+ }
+ case 16:
+ switch (pb->byte_order)
+ {
+ case BYTE_ORD_24_RGB:
+ return ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3);
+ case BYTE_ORD_24_BGR:
+ return ((b & 0xf8) << 8) | ((g & 0xfc) << 3) | ((r & 0xf8) >> 3);
+ }
+ case 24:
+ case 32:
+ switch (pb->byte_order)
+ {
+ case BYTE_ORD_24_RGB:
+ return ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff);
+ case BYTE_ORD_24_RBG:
+ return ((r & 0xff) << 16) | ((b & 0xff) << 8) | (g & 0xff);
+ case BYTE_ORD_24_BRG:
+ return ((b & 0xff) << 16) | ((r & 0xff) << 8) | (g & 0xff);
+ case BYTE_ORD_24_BGR:
+ return ((b & 0xff) << 16) | ((g & 0xff) << 8) | (r & 0xff);
+ case BYTE_ORD_24_GRB:
+ return ((g & 0xff) << 16) | ((r & 0xff) << 8) | (b & 0xff);
+ case BYTE_ORD_24_GBR:
+ return ((g & 0xff) << 16) | ((b & 0xff) << 8) | (r & 0xff);
+ case BYTE_ORD_32_ARGB:
+ return (a << 24) | (r << 16) | (g << 8) | b;
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
+/*
+ * Get pixel value from pointer to 16bpp data for pixel depth > 8
+ * and advance the pointer
+ *
+ * TODO ? We could take the 32bit case out of here, which would allow
+ * to ignore the alpha value for <15, 24>, but we might not gain that
+ * much by this on arm due to the conditional execution.
+ */
+static inline unsigned long
+mb_pixbuf_get_pixel_gt8_16bpp_advance (MBPixbuf *pb, unsigned char ** p,
+ int has_alpha)
+{
+ unsigned short s = SHORT_FROM_2BYTES(*p);
+ int r, b, g, a;
+
+ r = (s & 0xf800) >> 8;
+ g = (s & 0x07e0) >> 3;
+ b = (s & 0x001f) << 3;
+
+ *p += 2;
+
+ a = has_alpha ? *(*p)++ : 0xff;
+
+ return mb_pixbuf_get_pixel_gt8_rgba (pb, r, g, b, a);
+}
+
+static inline unsigned long
+mb_pixbuf_get_pixel(MBPixbuf *pb, int r, int g, int b, int a)
+{
+ if (pb->depth > 8)
+ return mb_pixbuf_get_pixel_gt8_rgba (pb, r, g, b, a);
+
+ return mb_pixbuf_get_pixel_le8_rgb (pb, r, g, b);
+}
+
unsigned long
mb_pixbuf_lookup_x_pixel(MBPixbuf *pb, int r, int g, int b, int a)
{
@@ -1825,7 +1903,6 @@
mb_pixbuf_img_render_to_drawable_with_gc(pb, img, drw, drw_x, drw_y, pb->gc);
}
-
void
mb_pixbuf_img_render_to_drawable_with_gc(MBPixbuf *pb,
MBPixbufImage *img,
@@ -1883,31 +1960,57 @@
if (pb->internal_bytespp == 2)
{
- for(y=0; y<img->height; y++)
- for(x=0; x<img->width; x++)
- {
- /* Below is potentially dangerous.
- */
- pixel = ( *p | (*(p+1) << 8));
-
- p += ((img->has_alpha) ? 3 : 2);
-
- XPutPixel(img->ximg, x, y, pixel);
- }
+ if (pb->depth > 8)
+ {
+ for(y=0; y<img->height; y++)
+ for(x=0; x<img->width; x++)
+ {
+ pixel = mb_pixbuf_get_pixel_gt8_16bpp_advance(pb, &p,
+ img->has_alpha);
+ XPutPixel(img->ximg, x, y, pixel);
+ }
+ }
+ else
+ {
+ for(y=0; y<img->height; y++)
+ for(x=0; x<img->width; x++)
+ {
+ pixel = mb_pixbuf_get_pixel_le8_16bpp_advance(pb, &p);
+ XPutPixel(img->ximg, x, y, pixel);
+ }
+ }
}
else
{
- for(y=0; y<img->height; y++)
+ if (pb->depth > 8)
{
- for(x=0; x<img->width; x++)
+ for(y=0; y<img->height; y++)
{
- r = ( *p++ );
- g = ( *p++ );
- b = ( *p++ );
- a = ((img->has_alpha) ? *p++ : 0xff);
+ for(x=0; x<img->width; x++)
+ {
+ r = ( *p++ );
+ g = ( *p++ );
+ b = ( *p++ );
+ a = ((img->has_alpha) ? *p++ : 0xff);
- pixel = mb_pixbuf_get_pixel(pb, r, g, b, a);
- XPutPixel(img->ximg, x, y, pixel);
+ pixel = mb_pixbuf_get_pixel_gt8_rgba(pb, r, g, b, a);
+ XPutPixel(img->ximg, x, y, pixel);
+ }
+ }
+ }
+ else
+ {
+ for(y=0; y<img->height; y++)
+ {
+ for(x=0; x<img->width; x++)
+ {
+ r = ( *p++ );
+ g = ( *p++ );
+ b = ( *p++ );
+
+ pixel = mb_pixbuf_get_pixel_le8_rgb(pb, r, g, b);
+ XPutPixel(img->ximg, x, y, pixel);
+ }
}
}
}