added generic slow-path rendering code

SVN revision: 3402
This commit is contained in:
Carsten Haitzler 2000-09-12 05:34:32 +00:00
parent aa70c777d2
commit 356c4db490
5 changed files with 176 additions and 28 deletions

3
TODO
View File

@ -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

View File

@ -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);
}

View File

@ -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)),

View File

@ -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

View File

@ -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);