From: Antonino Daplas <adaplas@pol.net>
To: James Simmons <jsimmons@infradead.org>
Cc: Linux console project <linuxconsole-dev@lists.sourceforge.net>,
Linux Fbdev development list
<linux-fbdev-devel@lists.sourceforge.net>
Subject: Re: status
Date: 23 Nov 2002 03:57:16 +0500 [thread overview]
Message-ID: <1038005868.13181.34.camel@localhost.localdomain> (raw)
In-Reply-To: <Pine.LNX.4.44.0211221902540.5899-100000@phoenix.infradead.org>
[-- Attachment #1: Type: text/plain, Size: 780 bytes --]
On Sat, 2002-11-23 at 00:04, James Simmons wrote:
>
> > 1. optimized putcs to speed up scrolling by 2-3x. (it's a small patch
> > but it already outperforms fb-2.4 especially at high color depths).
> > Compared with the previous patch I submitted, this change is
> > non-intrusive, so no other changes are required.
> >
> > 2. vga16fb imageblit that supports drawing of the penguin (vga-4-planes
> > only)
> >
> > 3. logo drawing for directcolor visuals.
>
> Please send me those patches ASAP!!! I will linclude them right away.
>
Okay. Instead of patches, I'll just attach a file with the targeted
functions which you can choose to cut and paste or modify as you see
fit.
vga16fb_imageblit in vga16fb.c
fbcon_show_logo in fbcon.c
fbcon_accel_putcs in fbcon-accel.c
[-- Attachment #2: changes.txt --]
[-- Type: text/plain, Size: 13428 bytes --]
/*
* James,
*
* fbcon_pixmap is where we construct the individual characters
* into a single combined bitmap before submitting in one burst
* to imageblit.
*
* Since you removed fbcon_accel_setup already, fbcon_pixmap
* can be statically allocated (max xres * max fontheight/8) which
* should be 4096 for a 2048 xres and a fontheight of 16. 8192 may
* be safer number.
*
* Also dynamic allocation segfaults when we do a kfree and hardware
* is still processing contents. This is where fb_sync() will be useful.
*/
static u8 *fbcon_pixmap = NULL;
void fbcon_accel_setup(struct display *p)
{
if (fbcon_pixmap != NULL) {
if (p->fb_info->fbops->fb_sync)
p->fb_info->fbops->fb_sync(p->fb_info);
kfree(fbcon_pixmap);
fbcon_pixmap = NULL;
}
fbcon_pixmap = kmalloc(fontheight(p) *
(p->fb_info->var.xres_virtual + 7)/8,
GFP_KERNEL);
p->next_line = p->fb_info->fix.line_length;
p->next_plane = 0;
}
void fbcon_accel_putcs(struct vc_data *vc, struct display *p,
const unsigned short *s, int count, int yy, int xx)
{
struct fb_info *info = p->fb_info;
unsigned short charmask = p->charmask;
unsigned int width = ((fontwidth(p) + 7) >> 3);
struct fb_image image;
unsigned int cellsize = fontheight(p) * width;
u16 c = scr_readw(s);
image.fg_color = attr_fgcol(p, c);
image.bg_color = attr_bgcol(p, c);
image.dx = xx * fontwidth(p);
image.dy = yy * fontheight(p);
image.height = fontheight(p);
image.depth = 1;
if (!(fontwidth(p) & 7) && fbcon_pixmap != NULL) {
unsigned int pitch = width * count, i, j;
char *src, *dst, *dst0;
dst0 = fbcon_pixmap;
image.width = fontwidth(p) * count;
image.data = fbcon_pixmap;
while (count--) {
src = p->fontdata + (scr_readw(s++) & charmask) * cellsize;
dst = dst0;
for (i = image.height; i--; ) {
for (j = 0; j < width; j++)
dst[j] = *src++;
dst += pitch;
}
dst0 += width;
}
info->fbops->fb_imageblit(info, &image);
}
else {
image.width = fontwidth(p);
while (count--) {
image.data = p->fontdata +
(scr_readw(s++) & charmask) * cellsize;
info->fbops->fb_imageblit(info, &image);
image.dx += fontwidth(p);
}
}
}
/*
* fbcon_show_logo that supports drawing using fb_imageblit. All packed
* pixel formats (truecolor, directcolor, pseudocolor) should now be
* supported. It also supports logo drawing with vga-4-planes as pseudocolor
* at 4 bpp.
*/
static int __init fbcon_show_logo( void )
{
struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
struct fb_info *info = p->fb_info;
#ifdef CONFIG_FBCON_ACCEL
struct fb_image image;
u32 *palette = NULL, *saved_palette = NULL;
char *logo_new = NULL;
#else
int line = p->next_line, x1, y1;
unsigned char *dst, *src;
#endif
int depth = info->var.bits_per_pixel;
unsigned char *fb = info->screen_base;
unsigned char *logo;
int i, j, n, x;
int logo_depth, done = 0;
/* Return if the frame buffer is not mapped */
if (!fb)
return 0;
/*
* Set colors if visual is PSEUDOCOLOR and we have enough colors, or for
* DIRECTCOLOR
* We don't have to set the colors for the 16-color logo, since that logo
* uses the standard VGA text console palette
*/
if ((info->fix.visual == FB_VISUAL_PSEUDOCOLOR && depth >= 8) ||
(info->fix.visual == FB_VISUAL_DIRECTCOLOR && depth >= 24))
for (i = 0; i < LINUX_LOGO_COLORS; i += n) {
n = LINUX_LOGO_COLORS - i;
if (n > 16)
/* palette_cmap provides space for only 16 colors at once */
n = 16;
palette_cmap.start = 32 + i;
palette_cmap.len = n;
for( j = 0; j < n; ++j ) {
palette_cmap.red[j] = (linux_logo_red[i+j] << 8) |
linux_logo_red[i+j];
palette_cmap.green[j] = (linux_logo_green[i+j] << 8) |
linux_logo_green[i+j];
palette_cmap.blue[j] = (linux_logo_blue[i+j] << 8) |
linux_logo_blue[i+j];
}
fb_set_cmap(&palette_cmap, 1, info);
}
if (depth >= 8) {
logo = linux_logo;
logo_depth = 8;
}
else if (depth >= 4) {
logo = linux_logo16;
logo_depth = 4;
}
else {
logo = linux_logo_bw;
logo_depth = 1;
}
#if defined(CONFIG_FBCON_ACCEL)
if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
(info->fix.visual == FB_VISUAL_DIRECTCOLOR && depth >= 24)) {
unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
unsigned char redmask, greenmask, bluemask;
int redshift, greenshift, blueshift;
/*
* We have to create a temporary palette since console palette is only
* 16 colors long.
*/
palette = kmalloc(256 * 4, GFP_KERNEL);
if (palette == NULL)
return (LOGO_H + fontheight(p) - 1) / fontheight(p);
if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
/* Bug: Doesn't obey msb_right ... (who needs that?) */
redmask = mask[info->var.red.length < 8 ? info->var.red.length : 8];
greenmask = mask[info->var.green.length < 8 ? info->var.green.length : 8];
bluemask = mask[info->var.blue.length < 8 ? info->var.blue.length : 8];
redshift = info->var.red.offset - (8 - info->var.red.length);
greenshift = info->var.green.offset - (8 - info->var.green.length);
blueshift = info->var.blue.offset - (8 - info->var.blue.length);
for ( i = 0; i < LINUX_LOGO_COLORS; i++) {
palette[i+32] = (safe_shift((linux_logo_red[i] & redmask), redshift) |
safe_shift((linux_logo_green[i] & greenmask), greenshift) |
safe_shift((linux_logo_blue[i] & bluemask), blueshift));
}
}
else {
redshift = info->var.red.offset;
greenshift = info->var.green.offset;
blueshift = info->var.blue.offset;
for (i = 32; i < LINUX_LOGO_COLORS; i++)
palette[i] = i << redshift | i << greenshift | i << blueshift;
}
saved_palette = info->pseudo_palette;
info->pseudo_palette = palette;
}
else if (info->fix.visual == FB_VISUAL_DIRECTCOLOR && depth >= 12 && depth < 24) {
logo_new = kmalloc(LOGO_W * LOGO_H, GFP_KERNEL);
if (logo_new == NULL)
return (LOGO_H + fontheight(p) - 1) / fontheight(p);
logo = logo_new;
for (i = 0; i < (LOGO_W * LOGO_H)/2; i++) {
logo_new[i*2] = linux_logo16[i] >> 4;
logo_new[(i*2)+1] = linux_logo16[i] & 0xf;
}
}
image.width = LOGO_W;
image.height = LOGO_H;
image.depth = depth;
image.data = logo;
image.dy = 0;
#endif
for (x = 0; x < num_online_cpus() * (LOGO_W + 8) &&
x < info->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
#if defined (CONFIG_FBCON_ACCEL)
image.dx = x;
info->fbops->fb_imageblit(info, &image);
done = 1;
#endif
#if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_ILBM) || \
defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
defined(CONFIG_FBCON_IPLAN2P8)
if (depth >= 2 && (info->fix.type == FB_TYPE_PLANES ||
info->fix.type == FB_TYPE_INTERLEAVED_PLANES)) {
/* planes (normal or interleaved), with color registers */
int bit;
unsigned char val, mask;
int plane = p->next_plane;
#if defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
defined(CONFIG_FBCON_IPLAN2P8)
int line_length = info->fix.line_length;
/* for support of Atari interleaved planes */
#define MAP_X(x) (line_length ? (x) : ((x) & ~1)*depth + ((x) & 1))
#else
#define MAP_X(x) (x)
#endif
/* extract a bit from the source image */
#define BIT(p,pix,bit) (p[pix*logo_depth/8] & \
(1 << ((8-((pix*logo_depth)&7)-logo_depth) + bit)))
src = logo;
for( y1 = 0; y1 < LOGO_H; y1++ ) {
for( x1 = 0; x1 < LOGO_LINE; x1++, src += logo_depth ) {
dst = fb + y1*line + MAP_X(x/8+x1);
for( bit = 0; bit < logo_depth; bit++ ) {
val = 0;
for( mask = 0x80, i = 0; i < 8; mask >>= 1, i++ ) {
if (BIT( src, i, bit ))
val |= mask;
}
*dst = val;
dst += plane;
}
}
}
/* fill remaining planes */
if (depth > logo_depth) {
for( y1 = 0; y1 < LOGO_H; y1++ ) {
for( x1 = 0; x1 < LOGO_LINE; x1++ ) {
dst = fb + y1*line + MAP_X(x/8+x1) + logo_depth*plane;
for( i = logo_depth; i < depth; i++, dst += plane )
*dst = 0x00;
}
}
}
done = 1;
break;
}
#endif
#if defined(CONFIG_FBCON_MFB) || defined(CONFIG_FBCON_AFB) || \
defined(CONFIG_FBCON_ILBM) || defined(CONFIG_FBCON_HGA)
if (depth == 1 && (info->fix.type == FB_TYPE_PACKED_PIXELS ||
info->fix.type == FB_TYPE_PLANES ||
info->fix.type == FB_TYPE_INTERLEAVED_PLANES)) {
/* monochrome */
unsigned char inverse = p->inverse || info->fix.visual == FB_VISUAL_MONO01
? 0x00 : 0xff;
int is_hga = !strncmp(info->modename, "HGA", 3);
/* can't use simply memcpy because need to apply inverse */
for( y1 = 0; y1 < LOGO_H; y1++ ) {
src = logo + y1*LOGO_LINE;
if (is_hga)
dst = fb + (y1%4)*8192 + (y1>>2)*line + x/8;
else
dst = fb + y1*line + x/8;
for( x1 = 0; x1 < LOGO_LINE; ++x1 )
fb_writeb(*src++ ^ inverse, dst++);
}
done = 1;
}
#endif
#if defined(CONFIG_FBCON_VGA_PLANES)
if (depth == 4 && info->fix.type == FB_TYPE_VGA_PLANES) {
outb_p(1,0x3ce); outb_p(0xf,0x3cf);
outb_p(3,0x3ce); outb_p(0,0x3cf);
outb_p(5,0x3ce); outb_p(0,0x3cf);
src = logo;
for (y1 = 0; y1 < LOGO_H; y1++) {
for (x1 = 0; x1 < LOGO_W / 2; x1++) {
dst = fb + y1*line + x1/4 + x/8;
outb_p(0,0x3ce);
outb_p(*src >> 4,0x3cf);
outb_p(8,0x3ce);
outb_p(1 << (7 - x1 % 4 * 2),0x3cf);
fb_readb (dst);
fb_writeb (0, dst);
outb_p(0,0x3ce);
outb_p(*src & 0xf,0x3cf);
outb_p(8,0x3ce);
outb_p(1 << (7 - (1 + x1 % 4 * 2)),0x3cf);
fb_readb (dst);
fb_writeb (0, dst);
src++;
}
}
done = 1;
}
#endif
}
#if defined (CONFIG_FBCON_ACCEL)
if (palette != NULL)
kfree(palette);
if (saved_palette != NULL)
info->pseudo_palette = saved_palette;
if (logo_new != NULL)
kfree(logo_new);
#endif
/* Modes not yet supported: packed pixels with depth != 8 (does such a
* thing exist in reality?) */
return done ? (LOGO_H + fontheight(p) - 1) / fontheight(p) : 0 ;
}
/*
* The following is a vga imageblit that supports bitmaps greater than
* 8 pixels wide and logo drawing in vga-4-planes.
*
* I haven't made any changes to the other VGA formats. No hardware.
*/
void vga_imageblit_expand(struct fb_info *info, struct fb_image *image)
{
char *where = info->screen_base + (image->dx/8) +
image->dy * info->fix.line_length;
struct vga16fb_par *par = (struct vga16fb_par *) info->par;
u8 *cdat = image->data, *dst;
int x, y;
switch (info->fix.type) {
case FB_TYPE_VGA_PLANES:
if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4) {
if (par->isVGA) {
setmode(2);
setop(0);
setsr(0xf);
setcolor(image->fg_color);
selectmask();
setmask(0xff);
writeb(image->bg_color, where);
rmb();
readb(where); /* fill latches */
setmode(3);
wmb();
for (y = 0; y < image->height; y++) {
dst = where;
for (x = image->width/8; x--;)
writeb(*cdat++, dst++);
where += info->fix.line_length;
}
wmb();
} else {
setmode(0);
setop(0);
setsr(0xf);
setcolor(image->bg_color);
selectmask();
setmask(0xff);
for (y = 0; y < image->height; y++) {
dst = where;
for (x=image->width/8; x--;){
rmw(dst);
setcolor(image->fg_color);
selectmask();
if (*cdat) {
setmask(*cdat++);
rmw(dst++);
}
}
where += info->fix.line_length;
}
}
} else
vga_8planes_imageblit(info, image);
break;
#ifdef FBCON_HAS_VGA
case FB_TYPE_TEXT:
break;
#endif
case FB_TYPE_PACKED_PIXELS:
default:
cfb_imageblit(info, image);
break;
}
}
void vga_imageblit_color(struct fb_info *info, struct fb_image *image)
{
/*
* Draw logo
*/
struct vga16fb_par *par = (struct vga16fb_par *) info->par;
char *where = info->screen_base + image->dy * info->fix.line_length +
image->dx/8;
char *cdat = image->data, *dst;
int x, y;
switch (info->fix.type) {
case FB_TYPE_VGA_PLANES:
if (info->fix.type_aux == FB_AUX_VGA_PLANES_VGA4 &&
par->isVGA) {
setsr(0xf);
setop(0);
setmode(0);
for (y = 0; y < image->height; y++) {
for (x = 0; x < image->width/2; x++) {
dst = where + x/4;
setcolor(*cdat >> 4);
selectmask();
setmask(1 << (7 - x % 4 * 2));
fb_readb(dst);
fb_writeb(0, dst);
setcolor(*cdat & 0xf);
selectmask();
setmask(1 << (7 - (1 + x % 4 * 2)));
fb_readb(dst);
fb_writeb(0, dst);
cdat++;
}
where += info->fix.line_length;
}
}
break;
case FB_TYPE_PACKED_PIXELS:
cfb_imageblit(info, image);
break;
default:
break;
}
}
void vga16fb_imageblit(struct fb_info *info, struct fb_image *image)
{
if (image->depth == 1)
vga_imageblit_expand(info, image);
else if (image->depth == info->var.bits_per_pixel)
vga_imageblit_color(info, image);
}
next prev parent reply other threads:[~2002-11-22 22:57 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-11-22 17:52 status James Simmons
2002-11-22 21:45 ` status Antonino Daplas
2002-11-22 19:04 ` status James Simmons
2002-11-22 22:12 ` status Antonino Daplas
2002-11-22 22:57 ` Antonino Daplas [this message]
2002-11-23 21:07 ` status Geert Uytterhoeven
2002-11-25 18:47 ` James Simmons
2002-11-25 21:35 ` Johan Bolmsjo
2002-11-26 0:39 ` James Simmons
2002-11-27 23:02 ` Geert Uytterhoeven
2002-12-08 11:47 ` Geert Uytterhoeven
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1038005868.13181.34.camel@localhost.localdomain \
--to=adaplas@pol.net \
--cc=jsimmons@infradead.org \
--cc=linux-fbdev-devel@lists.sourceforge.net \
--cc=linuxconsole-dev@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).