linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* fbcon_show_logo using imageblit
@ 2002-05-07 13:25 Antonino Daplas
  0 siblings, 0 replies; only message in thread
From: Antonino Daplas @ 2002-05-07 13:25 UTC (permalink / raw)
  To: fbdev

Hi,

I was trying to test the imageblit function to draw images, and while
doing that, I thought maybe I can use the fbcon_show_logo function for
testing.  I copied fbcon_show_logo as fbcon_show_logo_accel and slightly
modified the code so it uses imageblit instead. I only included
truecolor and psuedocolor at 8bpp since I don't have the hardware to
test other formats.

The code is probably suboptimal, but I would like to know if the
concept/format for using imageblit is correct. It does work on testing
though.

I included a diff for 2.5.13 + fbdev_fixs.diff (James Simmons).

Tony

--- fbcon.c.orig	Tue May  7 20:53:04 2002
+++ fbcon.c	Tue May  7 21:04:20 2002
@@ -215,6 +215,9 @@
 			    int height, int width, u_int y_break);
 
 static int fbcon_show_logo(void);
+#ifdef CONFIG_FBCON_ACCEL
+static int fbcon_show_logo_accel(void);
+#endif
 
 #ifdef CONFIG_MAC
 /*
@@ -1541,6 +1544,9 @@
 	p->dispsw->clear_margins(conp, p, 0);
     if (logo_shown == -2) {
 	logo_shown = fg_console;
+#ifdef CONFIG_FBCON_ACCEL
+	if (!(fbcon_show_logo_accel()))
+#endif
 	fbcon_show_logo(); /* This is protected above by initmem_freed */
 	update_region(fg_console,
 		      conp->vc_origin + conp->vc_size_row * conp->vc_top,
@@ -2447,6 +2453,143 @@
 
     return done ? (LOGO_H + fontheight(p) - 1) / fontheight(p) : 0 ;
 }
+
+#ifdef CONFIG_FBCON_ACCEL
+static int __init fbcon_show_logo_accel( void )
+{
+	struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
+	struct fb_image image;
+	int depth = p->var.bits_per_pixel;
+	unsigned char *logo;
+	unsigned char *dst, *src = 0, *data, *dat;
+	int i, j, n, x1, y1, x = 0;
+	int logo_depth, done = 0;
+	
+	if (!(p->fb_info->fbops->fb_imageblit))
+		return 0;
+	dat = (u8 *) (vmalloc(LOGO_W * LOGO_H * ((depth + 7) >> 3)));
+	if (dat == NULL) 
+		return 0;
+	data = dat;
+	/*
+	 * 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 ((p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 8) ||
+	    (p->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];
+			}
+			p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,
+						       p->fb_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 (p->fb_info->fbops->fb_rasterimg)
+		p->fb_info->fbops->fb_rasterimg(p->fb_info, 1);
+	
+#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
+    defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)
+	if ((depth % 8 == 0) && (p->visual == FB_VISUAL_TRUECOLOR)) {
+	    /* Modes without color mapping, needs special data transformation... */
+		unsigned int val;		/* max. depth 32! */
+		int bdepth = depth/8;
+		unsigned char redmask, greenmask, bluemask;
+		int redshift, greenshift, blueshift;
+		unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
+		
+		/* Bug: Doesn't obey msb_right ... (who needs that?) */
+		redmask   = mask[p->var.red.length   < 8 ? p->var.red.length   : 8];
+		greenmask = mask[p->var.green.length < 8 ? p->var.green.length : 8];
+		bluemask  = mask[p->var.blue.length  < 8 ? p->var.blue.length  : 8];
+		redshift   = p->var.red.offset   - (8-p->var.red.length);
+		greenshift = p->var.green.offset - (8-p->var.green.length);
+		blueshift  = p->var.blue.offset  - (8-p->var.blue.length);
+		
+		src = logo;
+		for( y1 = 0; y1 < LOGO_H; y1++ ) {
+			dst = data + y1*LOGO_W*bdepth;
+			for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
+				val = safe_shift((linux_logo_red[*src-32]   & redmask), redshift) |
+					safe_shift((linux_logo_green[*src-32] & greenmask), greenshift) |
+					safe_shift((linux_logo_blue[*src-32]  & bluemask), blueshift);
+				if (bdepth == 4 && !((long)dst & 3)) {
+					/* Some cards require 32bit access */
+					fb_writel (val, dst);
+					dst += 4;
+				} else if (bdepth == 2 && !((long)dst & 1)) {
+					/* others require 16bit access */
+					fb_writew (val,dst);
+					dst +=2;
+				} else {
+#ifdef __LITTLE_ENDIAN
+					for( i = 0; i < bdepth; ++i )
+#else
+					for( i = bdepth-1; i >= 0; --i )
+#endif
+						fb_writeb (val >> (i*8), dst++);
+				}
+			}
+		}
+		done = 1;
+	}
+#endif
+#if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FB_SBUS)
+	if (depth == 8 && p->type == FB_TYPE_PACKED_PIXELS) {
+		/* depth 8 or more, packed, with color registers */
+		data = logo;
+		done = 1;
+	}
+#endif
+	if (done) {
+		image.dy = 0;
+		image.height = LOGO_H;
+		image.width = LOGO_W;
+		image.depth = depth;
+		image.data = data;
+		for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
+			     x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
+			image.dx = x;
+			p->fb_info->fbops->fb_imageblit(p->fb_info, &image);
+		}
+	}
+	vfree(dat);
+	
+	if (p->fb_info->fbops->fb_rasterimg)
+		p->fb_info->fbops->fb_rasterimg(p->fb_info, 0);
+	
+    /* 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 ;
+}
+#endif
 
 /*
  *  The console `switch' structure for the frame buffer based console





_______________________________________________________________

Have big pipes? SourceForge.net is looking for download mirrors. We supply
the hardware. You get the recognition. Email Us: bandwidth@sourceforge.net

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2002-05-07 13:26 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-05-07 13:25 fbcon_show_logo using imageblit Antonino Daplas

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).