From: James S. <jsi...@ww...> - 2005-01-19 20:59:36
|
Here is a patch for packed pixel software imageblit. Since the code to draw a color image and a mono image are almost the same I merged them. Second I made the code generic enough to work on big endian and little endian code at the same time. I set my radeon card in my x86 box to big endian mode and tested. It worked for me but I like people on big endian machines to test it. The last fix was to deal with the 16 color logo. The fb_set_logo was unpacking the 4bpp info. Now cfb_imageblit can handle the logo data directly. Most hardware expects the data not to be unpacked. Another bug was image.depth was always set to 8 in fb_show_logo. This is in correct. Please test. Thank you. diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/cfbimgblt.c fbdev-2.6/drivers/video/cfbimgblt.c --- linus-2.6/drivers/video/cfbimgblt.c 2005-01-17 15:04:36.000000000 -0800 +++ fbdev-2.6/drivers/video/cfbimgblt.c 2005-01-16 18:24:22.000000000 -0800 @@ -33,6 +33,7 @@ #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> +#include <asm/byteorder.h> #include <asm/types.h> #define DEBUG @@ -44,29 +45,14 @@ #endif static u32 cfb_tab8[] = { -#if defined(__BIG_ENDIAN) - 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, - 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, - 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, - 0xffff0000,0xffff00ff,0xffffff00,0xffffffff -#elif defined(__LITTLE_ENDIAN) - 0x00000000,0xff000000,0x00ff0000,0xffff0000, - 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00, - 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff, - 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff -#else -#error FIXME: No endianness?? -#endif + 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, + 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, + 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, + 0xffff0000,0xffff00ff,0xffffff00,0xffffffff }; static u32 cfb_tab16[] = { -#if defined(__BIG_ENDIAN) - 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff -#elif defined(__LITTLE_ENDIAN) - 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff -#else -#error FIXME: No endianness?? -#endif + 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff }; static u32 cfb_tab32[] = { @@ -76,138 +62,83 @@ #define FB_WRITEL fb_writel #define FB_READL fb_readl -#if defined (__BIG_ENDIAN) -#define LEFT_POS(bpp) (32 - bpp) -#define SHIFT_HIGH(val, bits) ((val) >> (bits)) -#define SHIFT_LOW(val, bits) ((val) << (bits)) -#else -#define LEFT_POS(bpp) (0) #define SHIFT_HIGH(val, bits) ((val) << (bits)) #define SHIFT_LOW(val, bits) ((val) >> (bits)) -#endif -static inline void color_imageblit(const struct fb_image *image, - struct fb_info *p, u8 __iomem *dst1, - u32 start_index, - u32 pitch_index) +static inline void slow_imageblit(const struct fb_image *image, + struct fb_info *p, u8 __iomem *dst1, + u32 start_index, u32 pitch_index) { /* Draw the penguin */ - u32 __iomem *dst, *dst2; - u32 color = 0, val, shift; - int i, n, bpp = p->var.bits_per_pixel; - u32 null_bits = 32 - bpp; + int spitch = (image->width * image->depth + 7) >> 3; + const u32 *src = (const u32 *) image->data; + int scan_align = p->pixmap.scan_align - 1; u32 *palette = (u32 *) p->pseudo_palette; - const u8 *src = image->data; - - dst2 = (u32 __iomem *) dst1; - for (i = image->height; i--; ) { - n = image->width; - dst = (u32 __iomem *) dst1; - shift = 0; - val = 0; - - if (start_index) { - u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); - val = FB_READL(dst) & start_mask; - shift = start_index; - } - while (n--) { - if (p->fix.visual == FB_VISUAL_TRUECOLOR || - p->fix.visual == FB_VISUAL_DIRECTCOLOR ) - color = palette[*src]; - else - color = *src; - color <<= LEFT_POS(bpp); - val |= SHIFT_HIGH(color, shift); - if (shift >= null_bits) { - FB_WRITEL(val, dst++); - - val = (shift == null_bits) ? 0 : - SHIFT_LOW(color, 32 - shift); - } - shift += bpp; - shift &= (32 - 1); - src++; - } - if (shift) { - u32 end_mask = SHIFT_HIGH(~(u32)0, shift); - - FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); - } - dst1 += p->fix.line_length; - if (pitch_index) { - dst2 += p->fix.line_length; - dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1)); + int bits = p->pixmap.access_align << 3; + int i, n, bpp = p->var.bits_per_pixel; + u32 null_bits = bits - bpp, l = bits; + int mask = (1 << image->depth) - 1; + u32 color = 0, val, shift; + u32 __iomem *dst, *dst2; - start_index += pitch_index; - start_index &= 32 - 1; - } - } -} + spitch = (spitch + scan_align) & ~scan_align; -static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, - u8 __iomem *dst1, u32 fgcolor, - u32 bgcolor, - u32 start_index, - u32 pitch_index) -{ - u32 shift, color = 0, bpp = p->var.bits_per_pixel; - u32 __iomem *dst, *dst2; - u32 val, pitch = p->fix.line_length; - u32 null_bits = 32 - bpp; - u32 spitch = (image->width+7)/8; - const u8 *src = image->data, *s; - u32 i, j, l; - dst2 = (u32 __iomem *) dst1; - for (i = image->height; i--; ) { - shift = val = 0; - l = 8; - j = image->width; dst = (u32 __iomem *) dst1; - s = src; + shift = 0, val = 0; + n = image->width; /* write leading bits */ if (start_index) { - u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); + u32 start_mask = SHIFT_LOW(~(u32)0, bits - start_index); val = FB_READL(dst) & start_mask; shift = start_index; } - while (j--) { - l--; - color = (*s & (1 << l)) ? fgcolor : bgcolor; - color <<= LEFT_POS(bpp); + while (n--) { + if (!l) { src++; l = bits; } + l -= image->depth; + + color = (swab32p(src) & (mask << l)); + if (image->depth == 1) + color = color ? image->fg_color : image->bg_color; + else + color >>= l; + + if (p->fix.visual == FB_VISUAL_TRUECOLOR || + p->fix.visual == FB_VISUAL_DIRECTCOLOR) + color = palette[color]; + val |= SHIFT_HIGH(color, shift); - - /* Did the bitshift spill bits to the next long? */ + + /* Did the bitshift spill bits into the next long? */ if (shift >= null_bits) { FB_WRITEL(val, dst++); - val = (shift == null_bits) ? 0 : - SHIFT_LOW(color,32 - shift); + + val = (shift == null_bits) ? 0 : SHIFT_LOW(color, bits - shift); } shift += bpp; - shift &= (32 - 1); - if (!l) { l = 8; s++; }; + shift &= (bits - 1); } + l -= (spitch << 3) - image->width * image->depth; + /* write trailing bits */ - if (shift) { + if (shift) { u32 end_mask = SHIFT_HIGH(~(u32)0, shift); FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); } - - dst1 += pitch; - src += spitch; + + dst1 += p->fix.line_length; if (pitch_index) { - dst2 += pitch; - dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1)); + dst2 += p->fix.line_length; + dst1 = (u8 __iomem *)((long)dst2 & ~(p->pixmap.access_align - 1)); + start_index += pitch_index; - start_index &= 32 - 1; + start_index &= bits - 1; } - } } @@ -220,17 +151,29 @@ * beginning and end of a scanline is dword aligned */ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *p, - u8 __iomem *dst1, u32 fgcolor, - u32 bgcolor) + u8 __iomem *dst1) { - u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; - u32 ppw = 32/bpp, spitch = (image->width + 7)/8; + u32 fgx, fgcolor, bgx, bgcolor, bpp = p->var.bits_per_pixel; + int ppw = 32/bpp, spitch = (image->width + 7) >> 3; + int bit_access = p->pixmap.access_align << 3; + int scan_align = p->pixmap.scan_align - 1; u32 bit_mask, end_mask, eorx, shift; const char *s = image->data, *src; u32 __iomem *dst; u32 *tab = NULL; int i, j, k; - + + spitch = (spitch + scan_align) & ~scan_align; + + if (p->fix.visual == FB_VISUAL_TRUECOLOR || + p->fix.visual == FB_VISUAL_DIRECTCOLOR) { + fgx = fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; + bgx = bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; + } else { + fgx = fgcolor = image->fg_color; + bgx = bgcolor = image->bg_color; + } + switch (bpp) { case 8: tab = cfb_tab8; @@ -249,17 +192,17 @@ fgx |= fgcolor; bgx |= bgcolor; } - + + k = (image->width * bpp)/bit_access; bit_mask = (1 << ppw) - 1; eorx = fgx ^ bgx; - k = image->width/ppw; for (i = image->height; i--; ) { dst = (u32 __iomem *) dst1, shift = 8; src = s; - + for (j = k; j--; ) { shift -= ppw; - end_mask = tab[(*src >> shift) & bit_mask]; + end_mask = swab32(tab[(*src >> shift) & bit_mask]); FB_WRITEL((end_mask & eorx)^bgx, dst++); if (!shift) { shift = 8; src++; } } @@ -270,11 +213,11 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) { - u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; - u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; - u32 width = image->width, height = image->height; + u32 bpl = p->pixmap.access_align, bpp = p->var.bits_per_pixel; + u32 width = image->width, height = image->height; + u32 start_index, bitstart, pitch_index = 0; + int x2, y2, vxres, vyres, bits = bpl << 3; u32 dx = image->dx, dy = image->dy; - int x2, y2, vxres, vyres; u8 __iomem *dst1; if (p->state != FBINFO_STATE_RUNNING) @@ -299,36 +242,21 @@ width = x2 - dx; height = y2 - dy; - bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); - start_index = bitstart & (32 - 1); - pitch_index = (p->fix.line_length & (bpl - 1)) * 8; + bitstart = ((dy * p->fix.line_length) << 3) + (dx * bpp); + start_index = bitstart & (bits - 1); + pitch_index = (p->fix.line_length & (bpl - 1)) << 3; - bitstart /= 8; + bitstart >>= 3; bitstart &= ~(bpl - 1); dst1 = p->screen_base + bitstart; if (p->fbops->fb_sync) p->fbops->fb_sync(p); - if (image->depth == 1) { - if (p->fix.visual == FB_VISUAL_TRUECOLOR || - p->fix.visual == FB_VISUAL_DIRECTCOLOR) { - fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; - bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; - } else { - fgcolor = image->fg_color; - bgcolor = image->bg_color; - } - - if (32 % bpp == 0 && !start_index && !pitch_index && - ((width & (32/bpp-1)) == 0) && - bpp >= 8 && bpp <= 32) - fast_imageblit(image, p, dst1, fgcolor, bgcolor); - else - slow_imageblit(image, p, dst1, fgcolor, bgcolor, - start_index, pitch_index); - } else - color_imageblit(image, p, dst1, start_index, pitch_index); + if (bits % bpp == 0 && image->depth == 1 && !start_index && !pitch_index && bpp >= 8 && bpp <= 32 && ((width & (bits/bpp-1)) == 0)) + fast_imageblit(image, p, dst1); + else + slow_imageblit(image, p, dst1, start_index, pitch_index); } EXPORT_SYMBOL(cfb_imageblit); diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmem.c fbdev-2.6/drivers/video/fbmem.c --- linus-2.6/drivers/video/fbmem.c 2005-01-07 11:07:25.000000000 -0800 +++ fbdev-2.6/drivers/video/fbmem.c 2005-01-15 17:08:20.000000000 -0800 @@ -291,43 +291,6 @@ palette[i] = i << redshift | i << greenshift | i << blueshift; } -static void fb_set_logo(struct fb_info *info, - const struct linux_logo *logo, u8 *dst, - int depth) -{ - int i, j, k, fg = 1; - const u8 *src = logo->data; - u8 d, xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0; - - if (fb_get_color_depth(info) == 3) - fg = 7; - - switch (depth) { - case 4: - for (i = 0; i < logo->height; i++) - for (j = 0; j < logo->width; src++) { - *dst++ = *src >> 4; - j++; - if (j < logo->width) { - *dst++ = *src & 0x0f; - j++; - } - } - break; - case 1: - for (i = 0; i < logo->height; i++) { - for (j = 0; j < logo->width; src++) { - d = *src ^ xor; - for (k = 7; k >= 0; k--) { - *dst++ = ((d >> k) & 1) ? fg : 0; - j++; - } - } - } - break; - } -} - /* * Three (3) kinds of logo maps exist. linux_logo_clut224 (>16 colors), * linux_logo_vga16 (16 colors) and linux_logo_mono (2 colors). Depending on @@ -396,7 +359,7 @@ /* Return if no suitable logo was found */ fb_logo.logo = fb_find_logo(depth); - + if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { fb_logo.logo = NULL; return 0; @@ -414,7 +377,6 @@ int fb_show_logo(struct fb_info *info) { u32 *palette = NULL, *saved_pseudo_palette = NULL; - unsigned char *logo_new = NULL; struct fb_image image; int x; @@ -422,7 +384,7 @@ if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) return 0; - image.depth = 8; + image.depth = fb_logo.depth; image.data = fb_logo.logo->data; if (fb_logo.needs_cmapreset) @@ -443,20 +405,16 @@ info->pseudo_palette = palette; } - if (fb_logo.depth <= 4) { - logo_new = kmalloc(fb_logo.logo->width * fb_logo.logo->height, - GFP_KERNEL); - if (logo_new == NULL) { - if (palette) - kfree(palette); - if (saved_pseudo_palette) - info->pseudo_palette = saved_pseudo_palette; - return 0; + if (fb_logo.depth == 1) { + if (info->fix.visual == FB_VISUAL_MONO01) { + image.fg_color = 0; + image.bg_color = 1; + } else { + image.fg_color = 1; + image.bg_color = 0; } - image.data = logo_new; - fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); } - + image.width = fb_logo.logo->width; image.height = fb_logo.logo->height; image.dy = 0; @@ -471,8 +429,6 @@ kfree(palette); if (saved_pseudo_palette != NULL) info->pseudo_palette = saved_pseudo_palette; - if (logo_new != NULL) - kfree(logo_new); return fb_logo.logo->height; } #else |
From: <jsi...@pe...> - 2005-01-19 20:25:07
|
Here is a patch for packed pixel software imageblit. Since the code to draw a color image and a mono image are almost the same I merged them. Second I made the code generic enough to work on big endian and little endian code at the same time. I set my radeon card in my x86 box to big endian mode and tested. It worked for me but I like people on big endian machines to test it. The last fix was to deal with the 16 color logo. The fb_set_logo was unpacking the 4bpp info. Now cfb_imageblit can handle the logo data directly. Most hardware expects the data not to be unpacked. Another bug was image.depth was always set to 8 in fb_show_logo. This is in correct. Please test. Thank you. diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/cfbimgblt.c fbdev-2.6/drivers/video/cfbimgblt.c --- linus-2.6/drivers/video/cfbimgblt.c 2005-01-17 15:04:36.000000000 -0800 +++ fbdev-2.6/drivers/video/cfbimgblt.c 2005-01-16 18:24:22.000000000 -0800 @@ -33,6 +33,7 @@ #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> +#include <asm/byteorder.h> #include <asm/types.h> #define DEBUG @@ -44,29 +45,14 @@ #endif static u32 cfb_tab8[] = { -#if defined(__BIG_ENDIAN) - 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, - 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, - 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, - 0xffff0000,0xffff00ff,0xffffff00,0xffffffff -#elif defined(__LITTLE_ENDIAN) - 0x00000000,0xff000000,0x00ff0000,0xffff0000, - 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00, - 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff, - 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff -#else -#error FIXME: No endianness?? -#endif + 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, + 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, + 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, + 0xffff0000,0xffff00ff,0xffffff00,0xffffffff }; static u32 cfb_tab16[] = { -#if defined(__BIG_ENDIAN) - 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff -#elif defined(__LITTLE_ENDIAN) - 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff -#else -#error FIXME: No endianness?? -#endif + 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff }; static u32 cfb_tab32[] = { @@ -76,138 +62,83 @@ #define FB_WRITEL fb_writel #define FB_READL fb_readl -#if defined (__BIG_ENDIAN) -#define LEFT_POS(bpp) (32 - bpp) -#define SHIFT_HIGH(val, bits) ((val) >> (bits)) -#define SHIFT_LOW(val, bits) ((val) << (bits)) -#else -#define LEFT_POS(bpp) (0) #define SHIFT_HIGH(val, bits) ((val) << (bits)) #define SHIFT_LOW(val, bits) ((val) >> (bits)) -#endif -static inline void color_imageblit(const struct fb_image *image, - struct fb_info *p, u8 __iomem *dst1, - u32 start_index, - u32 pitch_index) +static inline void slow_imageblit(const struct fb_image *image, + struct fb_info *p, u8 __iomem *dst1, + u32 start_index, u32 pitch_index) { /* Draw the penguin */ - u32 __iomem *dst, *dst2; - u32 color = 0, val, shift; - int i, n, bpp = p->var.bits_per_pixel; - u32 null_bits = 32 - bpp; + int spitch = (image->width * image->depth + 7) >> 3; + const u32 *src = (const u32 *) image->data; + int scan_align = p->pixmap.scan_align - 1; u32 *palette = (u32 *) p->pseudo_palette; - const u8 *src = image->data; - - dst2 = (u32 __iomem *) dst1; - for (i = image->height; i--; ) { - n = image->width; - dst = (u32 __iomem *) dst1; - shift = 0; - val = 0; - - if (start_index) { - u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); - val = FB_READL(dst) & start_mask; - shift = start_index; - } - while (n--) { - if (p->fix.visual == FB_VISUAL_TRUECOLOR || - p->fix.visual == FB_VISUAL_DIRECTCOLOR ) - color = palette[*src]; - else - color = *src; - color <<= LEFT_POS(bpp); - val |= SHIFT_HIGH(color, shift); - if (shift >= null_bits) { - FB_WRITEL(val, dst++); - - val = (shift == null_bits) ? 0 : - SHIFT_LOW(color, 32 - shift); - } - shift += bpp; - shift &= (32 - 1); - src++; - } - if (shift) { - u32 end_mask = SHIFT_HIGH(~(u32)0, shift); - - FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); - } - dst1 += p->fix.line_length; - if (pitch_index) { - dst2 += p->fix.line_length; - dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1)); + int bits = p->pixmap.access_align << 3; + int i, n, bpp = p->var.bits_per_pixel; + u32 null_bits = bits - bpp, l = bits; + int mask = (1 << image->depth) - 1; + u32 color = 0, val, shift; + u32 __iomem *dst, *dst2; - start_index += pitch_index; - start_index &= 32 - 1; - } - } -} + spitch = (spitch + scan_align) & ~scan_align; -static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, - u8 __iomem *dst1, u32 fgcolor, - u32 bgcolor, - u32 start_index, - u32 pitch_index) -{ - u32 shift, color = 0, bpp = p->var.bits_per_pixel; - u32 __iomem *dst, *dst2; - u32 val, pitch = p->fix.line_length; - u32 null_bits = 32 - bpp; - u32 spitch = (image->width+7)/8; - const u8 *src = image->data, *s; - u32 i, j, l; - dst2 = (u32 __iomem *) dst1; - for (i = image->height; i--; ) { - shift = val = 0; - l = 8; - j = image->width; dst = (u32 __iomem *) dst1; - s = src; + shift = 0, val = 0; + n = image->width; /* write leading bits */ if (start_index) { - u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); + u32 start_mask = SHIFT_LOW(~(u32)0, bits - start_index); val = FB_READL(dst) & start_mask; shift = start_index; } - while (j--) { - l--; - color = (*s & (1 << l)) ? fgcolor : bgcolor; - color <<= LEFT_POS(bpp); + while (n--) { + if (!l) { src++; l = bits; } + l -= image->depth; + + color = (swab32p(src) & (mask << l)); + if (image->depth == 1) + color = color ? image->fg_color : image->bg_color; + else + color >>= l; + + if (p->fix.visual == FB_VISUAL_TRUECOLOR || + p->fix.visual == FB_VISUAL_DIRECTCOLOR) + color = palette[color]; + val |= SHIFT_HIGH(color, shift); - - /* Did the bitshift spill bits to the next long? */ + + /* Did the bitshift spill bits into the next long? */ if (shift >= null_bits) { FB_WRITEL(val, dst++); - val = (shift == null_bits) ? 0 : - SHIFT_LOW(color,32 - shift); + + val = (shift == null_bits) ? 0 : SHIFT_LOW(color, bits - shift); } shift += bpp; - shift &= (32 - 1); - if (!l) { l = 8; s++; }; + shift &= (bits - 1); } + l -= (spitch << 3) - image->width * image->depth; + /* write trailing bits */ - if (shift) { + if (shift) { u32 end_mask = SHIFT_HIGH(~(u32)0, shift); FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); } - - dst1 += pitch; - src += spitch; + + dst1 += p->fix.line_length; if (pitch_index) { - dst2 += pitch; - dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1)); + dst2 += p->fix.line_length; + dst1 = (u8 __iomem *)((long)dst2 & ~(p->pixmap.access_align - 1)); + start_index += pitch_index; - start_index &= 32 - 1; + start_index &= bits - 1; } - } } @@ -220,17 +151,29 @@ * beginning and end of a scanline is dword aligned */ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *p, - u8 __iomem *dst1, u32 fgcolor, - u32 bgcolor) + u8 __iomem *dst1) { - u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; - u32 ppw = 32/bpp, spitch = (image->width + 7)/8; + u32 fgx, fgcolor, bgx, bgcolor, bpp = p->var.bits_per_pixel; + int ppw = 32/bpp, spitch = (image->width + 7) >> 3; + int bit_access = p->pixmap.access_align << 3; + int scan_align = p->pixmap.scan_align - 1; u32 bit_mask, end_mask, eorx, shift; const char *s = image->data, *src; u32 __iomem *dst; u32 *tab = NULL; int i, j, k; - + + spitch = (spitch + scan_align) & ~scan_align; + + if (p->fix.visual == FB_VISUAL_TRUECOLOR || + p->fix.visual == FB_VISUAL_DIRECTCOLOR) { + fgx = fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; + bgx = bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; + } else { + fgx = fgcolor = image->fg_color; + bgx = bgcolor = image->bg_color; + } + switch (bpp) { case 8: tab = cfb_tab8; @@ -249,17 +192,17 @@ fgx |= fgcolor; bgx |= bgcolor; } - + + k = (image->width * bpp)/bit_access; bit_mask = (1 << ppw) - 1; eorx = fgx ^ bgx; - k = image->width/ppw; for (i = image->height; i--; ) { dst = (u32 __iomem *) dst1, shift = 8; src = s; - + for (j = k; j--; ) { shift -= ppw; - end_mask = tab[(*src >> shift) & bit_mask]; + end_mask = swab32(tab[(*src >> shift) & bit_mask]); FB_WRITEL((end_mask & eorx)^bgx, dst++); if (!shift) { shift = 8; src++; } } @@ -270,11 +213,11 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) { - u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; - u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; - u32 width = image->width, height = image->height; + u32 bpl = p->pixmap.access_align, bpp = p->var.bits_per_pixel; + u32 width = image->width, height = image->height; + u32 start_index, bitstart, pitch_index = 0; + int x2, y2, vxres, vyres, bits = bpl << 3; u32 dx = image->dx, dy = image->dy; - int x2, y2, vxres, vyres; u8 __iomem *dst1; if (p->state != FBINFO_STATE_RUNNING) @@ -299,36 +242,21 @@ width = x2 - dx; height = y2 - dy; - bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); - start_index = bitstart & (32 - 1); - pitch_index = (p->fix.line_length & (bpl - 1)) * 8; + bitstart = ((dy * p->fix.line_length) << 3) + (dx * bpp); + start_index = bitstart & (bits - 1); + pitch_index = (p->fix.line_length & (bpl - 1)) << 3; - bitstart /= 8; + bitstart >>= 3; bitstart &= ~(bpl - 1); dst1 = p->screen_base + bitstart; if (p->fbops->fb_sync) p->fbops->fb_sync(p); - if (image->depth == 1) { - if (p->fix.visual == FB_VISUAL_TRUECOLOR || - p->fix.visual == FB_VISUAL_DIRECTCOLOR) { - fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; - bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; - } else { - fgcolor = image->fg_color; - bgcolor = image->bg_color; - } - - if (32 % bpp == 0 && !start_index && !pitch_index && - ((width & (32/bpp-1)) == 0) && - bpp >= 8 && bpp <= 32) - fast_imageblit(image, p, dst1, fgcolor, bgcolor); - else - slow_imageblit(image, p, dst1, fgcolor, bgcolor, - start_index, pitch_index); - } else - color_imageblit(image, p, dst1, start_index, pitch_index); + if (bits % bpp == 0 && image->depth == 1 && !start_index && !pitch_index && bpp >= 8 && bpp <= 32 && ((width & (bits/bpp-1)) == 0)) + fast_imageblit(image, p, dst1); + else + slow_imageblit(image, p, dst1, start_index, pitch_index); } EXPORT_SYMBOL(cfb_imageblit); diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmem.c fbdev-2.6/drivers/video/fbmem.c --- linus-2.6/drivers/video/fbmem.c 2005-01-07 11:07:25.000000000 -0800 +++ fbdev-2.6/drivers/video/fbmem.c 2005-01-15 17:08:20.000000000 -0800 @@ -291,43 +291,6 @@ palette[i] = i << redshift | i << greenshift | i << blueshift; } -static void fb_set_logo(struct fb_info *info, - const struct linux_logo *logo, u8 *dst, - int depth) -{ - int i, j, k, fg = 1; - const u8 *src = logo->data; - u8 d, xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0; - - if (fb_get_color_depth(info) == 3) - fg = 7; - - switch (depth) { - case 4: - for (i = 0; i < logo->height; i++) - for (j = 0; j < logo->width; src++) { - *dst++ = *src >> 4; - j++; - if (j < logo->width) { - *dst++ = *src & 0x0f; - j++; - } - } - break; - case 1: - for (i = 0; i < logo->height; i++) { - for (j = 0; j < logo->width; src++) { - d = *src ^ xor; - for (k = 7; k >= 0; k--) { - *dst++ = ((d >> k) & 1) ? fg : 0; - j++; - } - } - } - break; - } -} - /* * Three (3) kinds of logo maps exist. linux_logo_clut224 (>16 colors), * linux_logo_vga16 (16 colors) and linux_logo_mono (2 colors). Depending on @@ -396,7 +359,7 @@ /* Return if no suitable logo was found */ fb_logo.logo = fb_find_logo(depth); - + if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { fb_logo.logo = NULL; return 0; @@ -414,7 +377,6 @@ int fb_show_logo(struct fb_info *info) { u32 *palette = NULL, *saved_pseudo_palette = NULL; - unsigned char *logo_new = NULL; struct fb_image image; int x; @@ -422,7 +384,7 @@ if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) return 0; - image.depth = 8; + image.depth = fb_logo.depth; image.data = fb_logo.logo->data; if (fb_logo.needs_cmapreset) @@ -443,20 +405,16 @@ info->pseudo_palette = palette; } - if (fb_logo.depth <= 4) { - logo_new = kmalloc(fb_logo.logo->width * fb_logo.logo->height, - GFP_KERNEL); - if (logo_new == NULL) { - if (palette) - kfree(palette); - if (saved_pseudo_palette) - info->pseudo_palette = saved_pseudo_palette; - return 0; + if (fb_logo.depth == 1) { + if (info->fix.visual == FB_VISUAL_MONO01) { + image.fg_color = 0; + image.bg_color = 1; + } else { + image.fg_color = 1; + image.bg_color = 0; } - image.data = logo_new; - fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); } - + image.width = fb_logo.logo->width; image.height = fb_logo.logo->height; image.dy = 0; @@ -471,8 +429,6 @@ kfree(palette); if (saved_pseudo_palette != NULL) info->pseudo_palette = saved_pseudo_palette; - if (logo_new != NULL) - kfree(logo_new); return fb_logo.logo->height; } #else |
From: Antonino A. D. <ad...@ho...> - 2005-01-25 12:59:05
|
On Thursday 20 January 2005 04:25, jsi...@pe... wrote: > Here is a patch for packed pixel software imageblit. Since the code to > draw a color image and a mono image are almost the same I merged them. > Second I made the code generic enough to work on big endian and little > endian code at the same time. I set my radeon card in my x86 box to big > endian mode and tested. It worked for me but I like people on big endian > machines to test it. The last fix was to deal with the 16 color logo. The > fb_set_logo was unpacking the 4bpp info. Now cfb_imageblit can handle the > logo data directly. Most hardware expects the data not to be unpacked. > Another bug was image.depth was always set to 8 in fb_show_logo. This is > in correct. Please test. Thank you. Hi James, Tested on vesafb: works Tested on rivafb: crashes on fb_show_logo(). Tony |
From: James S. <jsi...@ww...> - 2005-01-26 21:07:14
|
> Hi James, > > Tested on vesafb: works > Tested on rivafb: crashes on fb_show_logo(). Ug!! Which video card are you using,what logos are you attempting to draw, and if you could post the oops trace? This is really strange. I tested the code with Radeon, 3Dfx, NeoMagic, and the VesaFB driver. They all worked. Also the riva drives used cfb_imageblit for the logo. Tomorrow I will pull out my TNT2 card to see what happens. |
From: Zack S. <pl...@co...> - 2005-01-27 17:09:29
|
I just want to make a tangential comment, call it trivia almost, but if we wanted to use my in-kernel GUI -- FBUI -- to handle the graphics during startup, including the penguin image, or even to handle the virtual console terminal itself or the login prompt, then I expect that can be done. Zack Smith home.comcast.net/~plinius/fbui.html James Simmons wrote: >>Hi James, >> >>Tested on vesafb: works >>Tested on rivafb: crashes on fb_show_logo(). >> >> > >Ug!! Which video card are you using,what logos are you attempting to >draw, and if you could post the oops trace? This is really strange. I >tested the code with Radeon, 3Dfx, NeoMagic, and the VesaFB driver. They >all worked. Also the riva drives used cfb_imageblit for the logo. Tomorrow >I will pull out my TNT2 card to see what happens. > > >------------------------------------------------------- >This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting >Tool for open source databases. Create drag-&-drop reports. Save time >by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. >Download a FREE copy at http://www.intelliview.com/go/osdn_nl >_______________________________________________ >Linux-fbdev-devel mailing list >Lin...@li... >https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel > > > |
From: James S. <jsi...@ww...> - 2005-01-28 21:05:27
|
Actually I have taken a look at your code. It's has potential for selling to some embedded vendor. Alot of the stuff you add is indeed missing but mostly can be implemented with what we already have. For example: fb_clear is really fb_fillrect with a rop of ROP_CLEAR. This is something I know Petr has been asking for :-) Which I want to implement. fb_vline is a rectangle with a height of 1. fb_read_point,fb_point, and fb_hline are really struct fb_pixmap { inbuf outbuf } We really need a way to get framebuffer data which you did with fb_getpixels. I plan to expand fb_imageblit to create a image from the framebuffer. I like to see fb_read use this. Why a copyarea2 ? > I just want to make a tangential comment, call it trivia almost, > but if we wanted to use my in-kernel GUI -- FBUI -- to handle > the graphics during startup, including the penguin image, or > even to handle the virtual console terminal itself or the login > prompt, then I expect that can be done. > > Zack Smith > home.comcast.net/~plinius/fbui.html |
From: Zack S. <pl...@co...> - 2005-01-29 02:17:47
|
I'm all for replacing my low level functions with existing functions, since that will reduce the size of FBUI, plus if people have already written accelerated routines it could benefit FBUI greatly. James Simmons wrote: >Actually I have taken a look at your code. It's has potential for selling >to some embedded vendor. Alot of the stuff you add is indeed missing but >mostly can be implemented with what we already have. For example: > >fb_clear is really fb_fillrect with a rop of ROP_CLEAR. This is something >I know Petr has been asking for :-) Which I want to implement. > >fb_vline is a rectangle with a height of 1. > >fb_read_point,fb_point, and fb_hline are really > >struct fb_pixmap { > inbuf > outbuf >} > >We really need a way to get framebuffer data which you did with >fb_getpixels. I plan to expand fb_imageblit to create a image from >the framebuffer. I like to see fb_read use this. > >Why a copyarea2 ? > > > >>I just want to make a tangential comment, call it trivia almost, >>but if we wanted to use my in-kernel GUI -- FBUI -- to handle >>the graphics during startup, including the penguin image, or >>even to handle the virtual console terminal itself or the login >>prompt, then I expect that can be done. >> >>Zack Smith >>home.comcast.net/~plinius/fbui.html >> >> > > >------------------------------------------------------- >This SF.Net email is sponsored by: IntelliVIEW -- Interactive Reporting >Tool for open source databases. Create drag-&-drop reports. Save time >by over 75%! Publish reports on the web. Export to DOC, XLS, RTF, etc. >Download a FREE copy at http://www.intelliview.com/go/osdn_nl >_______________________________________________ >Linux-fbdev-devel mailing list >Lin...@li... >https://lists.sourceforge.net/lists/listinfo/linux-fbdev-devel > > > |
From: James S. <jsi...@ww...> - 2005-01-20 18:08:58
|
Oops. Need to CC Tony. Here is a patch for packed pixel software imageblit. Since the code to draw a color image and a mono image are almost the same I merged them. Second I made the code generic enough to work on big endian and little endian code at the same time. I set my radeon card in my x86 box to big endian mode and tested. It worked for me but I like people on big endian machines to test it. The last fix was to deal with the 16 color logo. The fb_set_logo was unpacking the 4bpp info. Now cfb_imageblit can handle the logo data directly. Most hardware expects the data not to be unpacked. Another bug was image.depth was always set to 8 in fb_show_logo. This is in correct. Please test. Thank you. diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/cfbimgblt.c fbdev-2.6/drivers/video/cfbimgblt.c --- linus-2.6/drivers/video/cfbimgblt.c 2005-01-17 15:04:36.000000000 -0800 +++ fbdev-2.6/drivers/video/cfbimgblt.c 2005-01-16 18:24:22.000000000 -0800 @@ -33,6 +33,7 @@ #include <linux/module.h> #include <linux/string.h> #include <linux/fb.h> +#include <asm/byteorder.h> #include <asm/types.h> #define DEBUG @@ -44,29 +45,14 @@ #endif static u32 cfb_tab8[] = { -#if defined(__BIG_ENDIAN) - 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, - 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, - 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, - 0xffff0000,0xffff00ff,0xffffff00,0xffffffff -#elif defined(__LITTLE_ENDIAN) - 0x00000000,0xff000000,0x00ff0000,0xffff0000, - 0x0000ff00,0xff00ff00,0x00ffff00,0xffffff00, - 0x000000ff,0xff0000ff,0x00ff00ff,0xffff00ff, - 0x0000ffff,0xff00ffff,0x00ffffff,0xffffffff -#else -#error FIXME: No endianness?? -#endif + 0x00000000,0x000000ff,0x0000ff00,0x0000ffff, + 0x00ff0000,0x00ff00ff,0x00ffff00,0x00ffffff, + 0xff000000,0xff0000ff,0xff00ff00,0xff00ffff, + 0xffff0000,0xffff00ff,0xffffff00,0xffffffff }; static u32 cfb_tab16[] = { -#if defined(__BIG_ENDIAN) - 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff -#elif defined(__LITTLE_ENDIAN) - 0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff -#else -#error FIXME: No endianness?? -#endif + 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff }; static u32 cfb_tab32[] = { @@ -76,138 +62,83 @@ #define FB_WRITEL fb_writel #define FB_READL fb_readl -#if defined (__BIG_ENDIAN) -#define LEFT_POS(bpp) (32 - bpp) -#define SHIFT_HIGH(val, bits) ((val) >> (bits)) -#define SHIFT_LOW(val, bits) ((val) << (bits)) -#else -#define LEFT_POS(bpp) (0) #define SHIFT_HIGH(val, bits) ((val) << (bits)) #define SHIFT_LOW(val, bits) ((val) >> (bits)) -#endif -static inline void color_imageblit(const struct fb_image *image, - struct fb_info *p, u8 __iomem *dst1, - u32 start_index, - u32 pitch_index) +static inline void slow_imageblit(const struct fb_image *image, + struct fb_info *p, u8 __iomem *dst1, + u32 start_index, u32 pitch_index) { /* Draw the penguin */ - u32 __iomem *dst, *dst2; - u32 color = 0, val, shift; - int i, n, bpp = p->var.bits_per_pixel; - u32 null_bits = 32 - bpp; + int spitch = (image->width * image->depth + 7) >> 3; + const u32 *src = (const u32 *) image->data; + int scan_align = p->pixmap.scan_align - 1; u32 *palette = (u32 *) p->pseudo_palette; - const u8 *src = image->data; - - dst2 = (u32 __iomem *) dst1; - for (i = image->height; i--; ) { - n = image->width; - dst = (u32 __iomem *) dst1; - shift = 0; - val = 0; - - if (start_index) { - u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); - val = FB_READL(dst) & start_mask; - shift = start_index; - } - while (n--) { - if (p->fix.visual == FB_VISUAL_TRUECOLOR || - p->fix.visual == FB_VISUAL_DIRECTCOLOR ) - color = palette[*src]; - else - color = *src; - color <<= LEFT_POS(bpp); - val |= SHIFT_HIGH(color, shift); - if (shift >= null_bits) { - FB_WRITEL(val, dst++); - - val = (shift == null_bits) ? 0 : - SHIFT_LOW(color, 32 - shift); - } - shift += bpp; - shift &= (32 - 1); - src++; - } - if (shift) { - u32 end_mask = SHIFT_HIGH(~(u32)0, shift); - - FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); - } - dst1 += p->fix.line_length; - if (pitch_index) { - dst2 += p->fix.line_length; - dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1)); + int bits = p->pixmap.access_align << 3; + int i, n, bpp = p->var.bits_per_pixel; + u32 null_bits = bits - bpp, l = bits; + int mask = (1 << image->depth) - 1; + u32 color = 0, val, shift; + u32 __iomem *dst, *dst2; - start_index += pitch_index; - start_index &= 32 - 1; - } - } -} + spitch = (spitch + scan_align) & ~scan_align; -static inline void slow_imageblit(const struct fb_image *image, struct fb_info *p, - u8 __iomem *dst1, u32 fgcolor, - u32 bgcolor, - u32 start_index, - u32 pitch_index) -{ - u32 shift, color = 0, bpp = p->var.bits_per_pixel; - u32 __iomem *dst, *dst2; - u32 val, pitch = p->fix.line_length; - u32 null_bits = 32 - bpp; - u32 spitch = (image->width+7)/8; - const u8 *src = image->data, *s; - u32 i, j, l; - dst2 = (u32 __iomem *) dst1; - for (i = image->height; i--; ) { - shift = val = 0; - l = 8; - j = image->width; dst = (u32 __iomem *) dst1; - s = src; + shift = 0, val = 0; + n = image->width; /* write leading bits */ if (start_index) { - u32 start_mask = ~(SHIFT_HIGH(~(u32)0, start_index)); + u32 start_mask = SHIFT_LOW(~(u32)0, bits - start_index); val = FB_READL(dst) & start_mask; shift = start_index; } - while (j--) { - l--; - color = (*s & (1 << l)) ? fgcolor : bgcolor; - color <<= LEFT_POS(bpp); + while (n--) { + if (!l) { src++; l = bits; } + l -= image->depth; + + color = (swab32p(src) & (mask << l)); + if (image->depth == 1) + color = color ? image->fg_color : image->bg_color; + else + color >>= l; + + if (p->fix.visual == FB_VISUAL_TRUECOLOR || + p->fix.visual == FB_VISUAL_DIRECTCOLOR) + color = palette[color]; + val |= SHIFT_HIGH(color, shift); - - /* Did the bitshift spill bits to the next long? */ + + /* Did the bitshift spill bits into the next long? */ if (shift >= null_bits) { FB_WRITEL(val, dst++); - val = (shift == null_bits) ? 0 : - SHIFT_LOW(color,32 - shift); + + val = (shift == null_bits) ? 0 : SHIFT_LOW(color, bits - shift); } shift += bpp; - shift &= (32 - 1); - if (!l) { l = 8; s++; }; + shift &= (bits - 1); } + l -= (spitch << 3) - image->width * image->depth; + /* write trailing bits */ - if (shift) { + if (shift) { u32 end_mask = SHIFT_HIGH(~(u32)0, shift); FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); } - - dst1 += pitch; - src += spitch; + + dst1 += p->fix.line_length; if (pitch_index) { - dst2 += pitch; - dst1 = (u8 __iomem *)((long __force)dst2 & ~(sizeof(u32) - 1)); + dst2 += p->fix.line_length; + dst1 = (u8 __iomem *)((long)dst2 & ~(p->pixmap.access_align - 1)); + start_index += pitch_index; - start_index &= 32 - 1; + start_index &= bits - 1; } - } } @@ -220,17 +151,29 @@ * beginning and end of a scanline is dword aligned */ static inline void fast_imageblit(const struct fb_image *image, struct fb_info *p, - u8 __iomem *dst1, u32 fgcolor, - u32 bgcolor) + u8 __iomem *dst1) { - u32 fgx = fgcolor, bgx = bgcolor, bpp = p->var.bits_per_pixel; - u32 ppw = 32/bpp, spitch = (image->width + 7)/8; + u32 fgx, fgcolor, bgx, bgcolor, bpp = p->var.bits_per_pixel; + int ppw = 32/bpp, spitch = (image->width + 7) >> 3; + int bit_access = p->pixmap.access_align << 3; + int scan_align = p->pixmap.scan_align - 1; u32 bit_mask, end_mask, eorx, shift; const char *s = image->data, *src; u32 __iomem *dst; u32 *tab = NULL; int i, j, k; - + + spitch = (spitch + scan_align) & ~scan_align; + + if (p->fix.visual == FB_VISUAL_TRUECOLOR || + p->fix.visual == FB_VISUAL_DIRECTCOLOR) { + fgx = fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; + bgx = bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; + } else { + fgx = fgcolor = image->fg_color; + bgx = bgcolor = image->bg_color; + } + switch (bpp) { case 8: tab = cfb_tab8; @@ -249,17 +192,17 @@ fgx |= fgcolor; bgx |= bgcolor; } - + + k = (image->width * bpp)/bit_access; bit_mask = (1 << ppw) - 1; eorx = fgx ^ bgx; - k = image->width/ppw; for (i = image->height; i--; ) { dst = (u32 __iomem *) dst1, shift = 8; src = s; - + for (j = k; j--; ) { shift -= ppw; - end_mask = tab[(*src >> shift) & bit_mask]; + end_mask = swab32(tab[(*src >> shift) & bit_mask]); FB_WRITEL((end_mask & eorx)^bgx, dst++); if (!shift) { shift = 8; src++; } } @@ -270,11 +213,11 @@ void cfb_imageblit(struct fb_info *p, const struct fb_image *image) { - u32 fgcolor, bgcolor, start_index, bitstart, pitch_index = 0; - u32 bpl = sizeof(u32), bpp = p->var.bits_per_pixel; - u32 width = image->width, height = image->height; + u32 bpl = p->pixmap.access_align, bpp = p->var.bits_per_pixel; + u32 width = image->width, height = image->height; + u32 start_index, bitstart, pitch_index = 0; + int x2, y2, vxres, vyres, bits = bpl << 3; u32 dx = image->dx, dy = image->dy; - int x2, y2, vxres, vyres; u8 __iomem *dst1; if (p->state != FBINFO_STATE_RUNNING) @@ -299,36 +242,21 @@ width = x2 - dx; height = y2 - dy; - bitstart = (dy * p->fix.line_length * 8) + (dx * bpp); - start_index = bitstart & (32 - 1); - pitch_index = (p->fix.line_length & (bpl - 1)) * 8; + bitstart = ((dy * p->fix.line_length) << 3) + (dx * bpp); + start_index = bitstart & (bits - 1); + pitch_index = (p->fix.line_length & (bpl - 1)) << 3; - bitstart /= 8; + bitstart >>= 3; bitstart &= ~(bpl - 1); dst1 = p->screen_base + bitstart; if (p->fbops->fb_sync) p->fbops->fb_sync(p); - if (image->depth == 1) { - if (p->fix.visual == FB_VISUAL_TRUECOLOR || - p->fix.visual == FB_VISUAL_DIRECTCOLOR) { - fgcolor = ((u32*)(p->pseudo_palette))[image->fg_color]; - bgcolor = ((u32*)(p->pseudo_palette))[image->bg_color]; - } else { - fgcolor = image->fg_color; - bgcolor = image->bg_color; - } - - if (32 % bpp == 0 && !start_index && !pitch_index && - ((width & (32/bpp-1)) == 0) && - bpp >= 8 && bpp <= 32) - fast_imageblit(image, p, dst1, fgcolor, bgcolor); - else - slow_imageblit(image, p, dst1, fgcolor, bgcolor, - start_index, pitch_index); - } else - color_imageblit(image, p, dst1, start_index, pitch_index); + if (bits % bpp == 0 && image->depth == 1 && !start_index && !pitch_index && bpp >= 8 && bpp <= 32 && ((width & (bits/bpp-1)) == 0)) + fast_imageblit(image, p, dst1); + else + slow_imageblit(image, p, dst1, start_index, pitch_index); } EXPORT_SYMBOL(cfb_imageblit); diff -urN -X /home/jsimmons/dontdiff linus-2.6/drivers/video/fbmem.c fbdev-2.6/drivers/video/fbmem.c --- linus-2.6/drivers/video/fbmem.c 2005-01-07 11:07:25.000000000 -0800 +++ fbdev-2.6/drivers/video/fbmem.c 2005-01-15 17:08:20.000000000 -0800 @@ -291,43 +291,6 @@ palette[i] = i << redshift | i << greenshift | i << blueshift; } -static void fb_set_logo(struct fb_info *info, - const struct linux_logo *logo, u8 *dst, - int depth) -{ - int i, j, k, fg = 1; - const u8 *src = logo->data; - u8 d, xor = (info->fix.visual == FB_VISUAL_MONO01) ? 0xff : 0; - - if (fb_get_color_depth(info) == 3) - fg = 7; - - switch (depth) { - case 4: - for (i = 0; i < logo->height; i++) - for (j = 0; j < logo->width; src++) { - *dst++ = *src >> 4; - j++; - if (j < logo->width) { - *dst++ = *src & 0x0f; - j++; - } - } - break; - case 1: - for (i = 0; i < logo->height; i++) { - for (j = 0; j < logo->width; src++) { - d = *src ^ xor; - for (k = 7; k >= 0; k--) { - *dst++ = ((d >> k) & 1) ? fg : 0; - j++; - } - } - } - break; - } -} - /* * Three (3) kinds of logo maps exist. linux_logo_clut224 (>16 colors), * linux_logo_vga16 (16 colors) and linux_logo_mono (2 colors). Depending on @@ -396,7 +359,7 @@ /* Return if no suitable logo was found */ fb_logo.logo = fb_find_logo(depth); - + if (!fb_logo.logo || fb_logo.logo->height > info->var.yres) { fb_logo.logo = NULL; return 0; @@ -414,7 +377,6 @@ int fb_show_logo(struct fb_info *info) { u32 *palette = NULL, *saved_pseudo_palette = NULL; - unsigned char *logo_new = NULL; struct fb_image image; int x; @@ -422,7 +384,7 @@ if (fb_logo.logo == NULL || info->state != FBINFO_STATE_RUNNING) return 0; - image.depth = 8; + image.depth = fb_logo.depth; image.data = fb_logo.logo->data; if (fb_logo.needs_cmapreset) @@ -443,20 +405,16 @@ info->pseudo_palette = palette; } - if (fb_logo.depth <= 4) { - logo_new = kmalloc(fb_logo.logo->width * fb_logo.logo->height, - GFP_KERNEL); - if (logo_new == NULL) { - if (palette) - kfree(palette); - if (saved_pseudo_palette) - info->pseudo_palette = saved_pseudo_palette; - return 0; + if (fb_logo.depth == 1) { + if (info->fix.visual == FB_VISUAL_MONO01) { + image.fg_color = 0; + image.bg_color = 1; + } else { + image.fg_color = 1; + image.bg_color = 0; } - image.data = logo_new; - fb_set_logo(info, fb_logo.logo, logo_new, fb_logo.depth); } - + image.width = fb_logo.logo->width; image.height = fb_logo.logo->height; image.dy = 0; @@ -471,8 +429,6 @@ kfree(palette); if (saved_pseudo_palette != NULL) info->pseudo_palette = saved_pseudo_palette; - if (logo_new != NULL) - kfree(logo_new); return fb_logo.logo->height; } #else |
From: Antonino A. D. <ad...@ho...> - 2005-01-20 22:00:18
|
On Friday 21 January 2005 02:08, James Simmons wrote: > Oops. Need to CC Tony. > > > Here is a patch for packed pixel software imageblit. Since the code to > draw a color image and a mono image are almost the same I merged them. > Second I made the code generic enough to work on big endian and little > endian code at the same time. I set my radeon card in my x86 box to big > endian mode and tested. It worked for me but I like people on big endian > machines to test it. The last fix was to deal with the 16 color logo. The > fb_set_logo was unpacking the 4bpp info. Now cfb_imageblit can handle the > logo data directly. Most hardware expects the data not to be unpacked. > Another bug was image.depth was always set to 8 in fb_show_logo. This is > in correct. Please test. Thank you. Hi James, how are you doing :-) ? The patch looks good, I'll do a few tests. Tony P.S: Any chance you want to maintain the fb layer again, let me know... |
From: James S. <jsi...@ww...> - 2005-01-21 00:29:10
|
> Hi James, how are you doing :-) ? Bette :-) > The patch looks good, I'll do a few tests. Great. It needs to be tested on a real big endian machine. > P.S: Any chance you want to maintain the fb layer again, let me know... I rather work with you maintaining the fbdev layer. Its alot of work for one person. |
From: James S. <jsi...@ww...> - 2005-01-31 19:25:19
|
I found the bug for this patch. I problem is that the new cfb_imageblit uses the pixmap access_align value. This was not being set in fbdev.c for the NVIDIA driver. The original reason for having pixmap in the NVIDIA driver was because the hardware needed images to be word padded. Now the standard soft accel functions also use word padded images by default. So I would suggest that we could remove the pixmap code from fbdev.c. What do you think? I also noticed a few drivers using it when they don't need it. Its due to the lack of documentation. I need to write some. |