From 356c4db490a6297731729274f43e1214adc743b5 Mon Sep 17 00:00:00 2001 From: Carsten Haitzler Date: Tue, 12 Sep 2000 05:34:32 +0000 Subject: [PATCH] added generic slow-path rendering code SVN revision: 3402 --- TODO | 3 -- src/color.c | 2 +- src/rend.c | 84 +++++++++++++++++++++++++++++++++++---- src/rgba.c | 111 +++++++++++++++++++++++++++++++++++++++++++++------- src/rgba.h | 4 +- 5 files changed, 176 insertions(+), 28 deletions(-) diff --git a/TODO b/TODO index 897196c..46b48b5 100644 --- a/TODO +++ b/TODO @@ -1,4 +1 @@ -* write generic "slow path" renderign code and make sure all fast -path rendering is correct for that visual -* formalize loader/saver api * fix loaders to only build if libs are present diff --git a/src/color.c b/src/color.c index 5d85f9e..a3db48c 100644 --- a/src/color.c +++ b/src/color.c @@ -19,7 +19,7 @@ __imlib_XActualDepth(Display *d, Visual *v) { depth = xvir[0].depth; if ((depth == 16) && - ((xvir->red_mask | xvir->green_mask | xvir->blue_mask) != 0xffff)) + ((xvir->red_mask | xvir->green_mask | xvir->blue_mask) == 0x7fff)) depth = 15; XFree(xvir); } diff --git a/src/rend.c b/src/rend.c index cd5120c..71a45dd 100644 --- a/src/rend.c +++ b/src/rend.c @@ -22,6 +22,70 @@ if (y < (yy)) {h += (y - (yy)); y = (yy);} \ if ((x + w) > ((xx) + (ww))) {w = (ww) - x;} \ if ((y + h) > ((yy) + (hh))) {h = (hh) - y;} +void +__imlib_generic_render(DATA32 *src, int jump, int w, int h, int dx, int dy, + XImage *xim, Visual *v) +{ + unsigned int x, y, r, g, b, val, hh; + unsigned int rmask, gmask, bmask; + int i, rshift, gshift, bshift; + + rmask = xim->red_mask; + gmask = xim->green_mask; + bmask = xim->blue_mask; + rshift = 0; + gshift = 0; + bshift = 0; + for (i = 31; i >= 0; i--) + { + if (rmask >= (1 << i)) + { + rshift = i - 7; + break; + } + } + for (i = 31; i >= 0; i--) + { + if (gmask >= (1 << i)) + { + gshift = i - 7; + break; + } + } + for (i = 31; i >= 0; i--) + { + if (bmask >= (1 << i)) + { + bshift = i - 7; + break; + } + } + hh = dy + h; + for (y = dy; y < hh; y++) + { + for (x = dx; x < w; x++) + { + r = R_VAL(src); + if (rshift >= 0) + val = ((r << rshift) & rmask); + else + val = ((r >> (-rshift)) & rmask); + g = G_VAL(src); + if (gshift >= 0) + val |= ((g << gshift) & gmask); + else + val |= ((g >> (-gshift)) & gmask); + b = B_VAL(src); + if (bshift >= 0) + val |= ((b << bshift) & bmask); + else + val |= ((b >> (-bshift)) & bmask); + XPutPixel(xim, x, y, val); + src++; + } + } +} + void __imlib_RenderImage(Display *d, ImlibImage *im, Drawable w, Drawable m, @@ -42,7 +106,7 @@ __imlib_RenderImage(Display *d, ImlibImage *im, ImlibScaleInfo *scaleinfo = NULL; int psx, psy, psw, psh; int actual_depth = 0; - char shm = 0, bgr = 0; + char shm = 0; ImlibRGBAFunction rgbaer, masker; ImlibBlendFunction blender = NULL; int do_mmx; @@ -96,9 +160,7 @@ __imlib_RenderImage(Display *d, ImlibImage *im, actual_depth = depth; if (depth == 16) actual_depth = __imlib_XActualDepth(d, v); - if (v->blue_mask > v->red_mask) - bgr = 1; - __imlib_RGBASetupContext(ct); + __imlib_RGBASetupContext(ct); if ((blend) && (IMAGE_HAS_ALPHA(im))) { back = malloc(dw *dh *sizeof(DATA32)); @@ -149,7 +211,9 @@ __imlib_RenderImage(Display *d, ImlibImage *im, h = dh; /* scale in LINESIZE Y chunks and convert to depth*/ /*\ Get rgba and mask functions for XImage rendering \*/ - rgbaer = __imlib_GetRGBAFunction(actual_depth, bgr, hiq, ct->palette_type); + rgbaer = __imlib_GetRGBAFunction(xim->bits_per_pixel, + v->red_mask, v->green_mask, v->blue_mask, + hiq, ct->palette_type); if (m) masker = __imlib_GetMaskFunction(dither_mask); #ifdef DO_MMX_ASM do_mmx = __imlib_get_cpuid() & CPUID_MMX; @@ -226,9 +290,13 @@ __imlib_RenderImage(Display *d, ImlibImage *im, jump = 0; } /* once scaled... convert chunk to bit depth into XImage bufer */ - rgbaer(pointer, jump, - ((DATA8 *)xim->data) + (y * (xim->bytes_per_line)), - xim->bytes_per_line, dw, hh, dx, dy + y); +/* if (rgbaer)*/ + if (0) + rgbaer(pointer, jump, + ((DATA8 *)xim->data) + (y * (xim->bytes_per_line)), + xim->bytes_per_line, dw, hh, dx, dy + y); + else + __imlib_generic_render(pointer, jump, dw, hh, 0, y, xim, v); if (m) masker(pointer, jump, ((DATA8 *)mxim->data) + (y * (mxim->bytes_per_line)), diff --git a/src/rgba.c b/src/rgba.c index e2f5d76..b416c06 100644 --- a/src/rgba.c +++ b/src/rgba.c @@ -3437,7 +3437,9 @@ __imlib_RGBA_to_Nothing(DATA32 *src , int src_jump, } ImlibRGBAFunction -__imlib_GetRGBAFunction(int depth, char bgr, char hiq, DATA8 palette_type) +__imlib_GetRGBAFunction(int depth, + unsigned long rm, unsigned long gm, unsigned long bm, + char hiq, DATA8 palette_type) { unsigned int did; static ImlibRGBAFunction functions[11][2][2] = { @@ -3490,22 +3492,101 @@ __imlib_GetRGBAFunction(int depth, char bgr, char hiq, DATA8 palette_type) { &__imlib_RGBA_to_RGB1_fast, &__imlib_RGBA_to_RGB1_dither } }, }; #endif - switch (depth) { - case 15: did = 0; break; - case 16: did = 1; break; - case 24: did = 2; break; - case 32: did = 3; break; - case 8: did = palette_type + 4; break; - default: return __imlib_RGBA_to_Nothing; - } - if (did >= 11) return __imlib_RGBA_to_Nothing; - /*\ Boolean sanity \*/ - bgr = bgr ? 1 : 0; hiq = hiq ? 1 : 0; + if (depth == 16) + { + if (hiq) + { + if ((rm == 0xf800) && (gm == 0x7e0) && (bm == 0x1f)) + return __imlib_RGBA_to_RGB565_dither; + if ((rm == 0x7c00) && (gm == 0x3e0) && (bm == 0x1f)) + return __imlib_RGBA_to_RGB555_dither; + if ((bm == 0xf800) && (gm == 0x7e0) && (rm == 0x1f)) + return __imlib_RGBA_to_BGR565_dither; + if ((bm == 0x7c00) && (gm == 0x3e0) && (rm == 0x1f)) + return __imlib_RGBA_to_BGR555_dither; + } + else + { #ifdef DO_MMX_ASM - if (__imlib_get_cpuid() && CPUID_MMX) - return mmx_functions[did][bgr][hiq]; + if (__imlib_get_cpuid() && CPUID_MMX) + { + if ((rm == 0xf800) && (gm == 0x7e0) && (bm == 0x1f)) + return __imlib_mmx_rgb565_fast; + if ((rm == 0x7c00) && (gm == 0x3e0) && (bm == 0x1f)) + return __imlib_mmx_rgb555_fast; + if ((bm == 0xf800) && (gm == 0x7e0) && (rm == 0x1f)) + return __imlib_mmx_bgr565_fast; + if ((bm == 0x7c00) && (gm == 0x3e0) && (rm == 0x1f)) + return __imlib_mmx_bgr555_fast; + } + else #endif - return functions[did][bgr][hiq]; + { + if ((rm == 0xf800) && (gm == 0x7e0) && (bm == 0x1f)) + return __imlib_RGBA_to_RGB565_fast; + if ((rm == 0x7c00) && (gm == 0x3e0) && (bm == 0x1f)) + return __imlib_RGBA_to_RGB555_fast; + if ((bm == 0xf800) && (gm == 0x7e0) && (rm == 0x1f)) + return __imlib_RGBA_to_BGR565_fast; + if ((bm == 0x7c00) && (gm == 0x3e0) && (rm == 0x1f)) + return __imlib_RGBA_to_BGR555_fast; + } + } + return NULL; + } + else if (depth == 32) + { + if ((rm == 0xff0000) && (gm == 0xff00) && (bm == 0xff)) + return __imlib_RGBA_to_RGB8888_fast; + return NULL; + } + else if (depth == 24) + { + if ((rm == 0xff0000) && (gm == 0xff00) && (bm == 0xff)) + return __imlib_RGBA_to_RGB888_fast; + return NULL; + } + else if (depth == 8) + { + if (hiq) + { + if (palette_type == 0) + return __imlib_RGBA_to_RGB232_dither; + if (palette_type == 1) + return __imlib_RGBA_to_RGB222_dither; + if (palette_type == 2) + return __imlib_RGBA_to_RGB221_dither; + if (palette_type == 3) + return __imlib_RGBA_to_RGB121_dither; + if (palette_type == 4) + return __imlib_RGBA_to_RGB111_dither; + if (palette_type == 5) + return __imlib_RGBA_to_RGB1_dither; + } + else + { + if (palette_type == 0) + return __imlib_RGBA_to_RGB232_fast; + if (palette_type == 1) + return __imlib_RGBA_to_RGB222_fast; + if (palette_type == 2) + return __imlib_RGBA_to_RGB221_fast; + if (palette_type == 3) + return __imlib_RGBA_to_RGB121_fast; + if (palette_type == 4) + return __imlib_RGBA_to_RGB111_fast; + if (palette_type == 5) + return __imlib_RGBA_to_RGB1_fast; + } + /* FIXME: return 1 byte rendering for mask */ + } + else if (depth == 1) + { + printf("Imlib2: eeek! cannot handle depth 1\n"); + return NULL; + } + printf("Imlib2: unknown depth %i\n", depth); + return NULL; } ImlibRGBAFunction diff --git a/src/rgba.h b/src/rgba.h index b430025..a668159 100644 --- a/src/rgba.h +++ b/src/rgba.h @@ -8,7 +8,9 @@ void __imlib_RGBA_init(void *rd, void *gd, void *bd, int depth, typedef void (*ImlibRGBAFunction)(DATA32*, int, DATA8*, int, int, int, int, int); ImlibRGBAFunction -__imlib_GetRGBAFunction(int depth, char bgr, char hiq, DATA8 palette_type); +__imlib_GetRGBAFunction(int depth, + unsigned long rm, unsigned long gm, unsigned long bm, + char hiq, DATA8 palette_type); ImlibRGBAFunction __imlib_GetMaskFunction(char hiq);