linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Antonino Daplas <adaplas@pol.net>
To: Antonino Daplas <adaplas@pol.net>
Cc: James Simmons <jsimmons@infradead.org>,
	Linux Fbdev development list
	<linux-fbdev-devel@lists.sourceforge.net>
Subject: Re: [PATCH] Tile Blitting
Date: 23 Feb 2003 15:43:13 +0800	[thread overview]
Message-ID: <1045986190.1189.2.camel@localhost.localdomain> (raw)
In-Reply-To: <1045975269.1676.18.camel@localhost.localdomain>

[-- Attachment #1: Type: text/plain, Size: 375 bytes --]

On Sun, 2003-02-23 at 12:42, Antonino Daplas wrote:

> Here's an updated Tile Blitting patch.  The feature is selectable via
> kernel configuration (under Advanced Low Level Driver Features). 
> Currently, it detects the presence of info->tileops but bit setting
> info->caps should be better.

Stupid me :-(, the patch does not work properly.  Try this one instead.

Tony



[-- Attachment #2: tileblit1.diff --]
[-- Type: text/x-patch, Size: 32864 bytes --]

diff -Naur linux-2.5.61-fbdev/drivers/video/console/Kconfig linux-2.5.61/drivers/video/console/Kconfig
--- linux-2.5.61-fbdev/drivers/video/console/Kconfig	2003-02-16 00:49:23.000000000 +0000
+++ linux-2.5.61/drivers/video/console/Kconfig	2003-02-23 06:42:26.000000000 +0000
@@ -136,6 +136,16 @@
 
 	  If unsure, say N.
 
+config FBCON_ADVANCED_TILEBLIT
+	bool "Support for Tile Blitting Operations"
+	depends on FBCON_ADVANCED
+	---help---
+          If you say Y, Tile Blitting support will be added.  Tile blitting is
+          a drawing operation, but its basic operating unit is a bitmap (in
+          contrast to Classic Blitting which operate on pixels).  This is 
+          necessary for drivers with Text Mode support.
+
+          If unsure, say N.
 # Guess what we need
 
 config FONT_SUN8x16
diff -Naur linux-2.5.61-fbdev/drivers/video/console/Makefile linux-2.5.61/drivers/video/console/Makefile
--- linux-2.5.61-fbdev/drivers/video/console/Makefile	2003-02-16 00:49:23.000000000 +0000
+++ linux-2.5.61/drivers/video/console/Makefile	2003-02-23 07:01:01.000000000 +0000
@@ -16,6 +16,10 @@
 
 font-objs += $(font-objs-y)
 
+fbcon_adv-objs := fbcon_accelops.o
+fbcon_adv-objs-$(CONFIG_FBCON_ADVANCED_TILEBLIT) += fbcon_tileops.o
+fbcon_adv-objs += $(fbcon_adv-objs-y)
+
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
@@ -24,7 +28,7 @@
 obj-$(CONFIG_STI_CONSOLE)         += sticon.o sticore.o
 obj-$(CONFIG_VGA_CONSOLE)         += vgacon.o
 obj-$(CONFIG_MDA_CONSOLE)         += mdacon.o
-obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o font.o
+obj-$(CONFIG_FRAMEBUFFER_CONSOLE) += fbcon.o font.o fbcon_adv.o
 
 obj-$(CONFIG_FB_STI)              += sticore.o
 
diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon.c linux-2.5.61/drivers/video/console/fbcon.c
--- linux-2.5.61-fbdev/drivers/video/console/fbcon.c	2003-02-22 02:34:26.000000000 +0000
+++ linux-2.5.61/drivers/video/console/fbcon.c	2003-02-23 06:45:15.000000000 +0000
@@ -295,136 +295,7 @@
 	take_over_console(&fb_con, unit, unit, fbcon_is_default);
 }
 
-/*
- * Accelerated handlers.
- */
-void accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
-			int height, int width)
-{
-	struct fb_info *info = p->fb_info;
-	struct vc_data *vc = p->conp;
-	struct fb_copyarea area;
-
-	area.sx = sx * vc->vc_font.width;
-	area.sy = sy * vc->vc_font.height;
-	area.dx = dx * vc->vc_font.width;
-	area.dy = dy * vc->vc_font.height;
-	area.height = height * vc->vc_font.height;
-	area.width = width * vc->vc_font.width;
-
-	info->fbops->fb_copyarea(info, &area);
-}
-
-void accel_clear(struct vc_data *vc, struct display *p, int sy,
-			int sx, int height, int width)
-{
-	struct fb_info *info = p->fb_info;
-	struct fb_fillrect region;
-
-	region.color = attr_bgcol_ec(p, vc);
-	region.dx = sx * vc->vc_font.width;
-	region.dy = sy * vc->vc_font.height;
-	region.width = width * vc->vc_font.width;
-	region.height = height * vc->vc_font.height;
-	region.rop = ROP_COPY;
-
-	info->fbops->fb_fillrect(info, &region);
-}	
-
-#define FB_PIXMAPSIZE 8192
-void 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 = ((vc->vc_font.width + 7)/8);
-	unsigned int cellsize = vc->vc_font.height * width;
-	struct fb_image image;
-	u16 c = scr_readw(s);
-	static u8 pixmap[FB_PIXMAPSIZE];
-	
-	image.fg_color = attr_fgcol(p, c);
-	image.bg_color = attr_bgcol(p, c);
-	image.dx = xx * vc->vc_font.width;
-	image.dy = yy * vc->vc_font.height;
-	image.height = vc->vc_font.height;
-	image.depth = 0;
-
-	if (!(vc->vc_font.width & 7)) {
-		unsigned int pitch, cnt, i, j, k;
-		unsigned int maxcnt = FB_PIXMAPSIZE/cellsize;
-		char *src, *dst, *dst0;
-
-		image.data = pixmap;
-		while (count) {
-			if (count > maxcnt) 
-				cnt = k = maxcnt;
-			else
-				cnt = k = count;
-			
-			dst0 = pixmap;
-			pitch = width * cnt;
-			image.width = vc->vc_font.width * cnt;
-			while (k--) {
-				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);
-			image.dx += cnt * vc->vc_font.width;
-			count -= cnt;
-		}
-	} else {
-		image.width = vc->vc_font.width;
-		while (count--) {
-			image.data = p->fontdata + 
-				(scr_readw(s++) & charmask) * cellsize;
-			info->fbops->fb_imageblit(info, &image);
-			image.dx += vc->vc_font.width;
-		}	
-	}
-}
-
-void accel_clear_margins(struct vc_data *vc, struct display *p,
-				int bottom_only)
-{
-	struct fb_info *info = p->fb_info;
-	unsigned int cw = vc->vc_font.width;
-	unsigned int ch = vc->vc_font.height;
-	unsigned int rw = info->var.xres % cw;
-	unsigned int bh = info->var.yres % ch;
-	unsigned int rs = info->var.xres - rw;
-	unsigned int bs = info->var.yres - bh;
-	struct fb_fillrect region;
-
-	region.color = attr_bgcol_ec(p, vc);
-	region.rop = ROP_COPY;
-
-	if (rw & !bottom_only) {
-		region.dx = info->var.xoffset + rs;
-		region.dy = 0;
-		region.width = rw;
-		region.height = info->var.yres_virtual;
-		info->fbops->fb_fillrect(info, &region);
-	}
-
-	if (bh) {
-		region.dx = info->var.xoffset;
-		region.dy = info->var.yoffset + bs;
-		region.width = rs;
-		region.height = bh;
-		info->fbops->fb_fillrect(info, &region);
-	}	
-}	
-
-void accel_cursor(struct display *p, int flags, int xx, int yy)
+void fb_cursor(struct display *p, int flags, int xx, int yy)
 {
 	static char mask[64], image[64], *dest;
 	struct vc_data *vc = p->conp;
@@ -743,6 +614,13 @@
 	int i, charcnt = 256;
 	struct font_desc *font;
 
+#ifdef CONFIG_FBCON_ADVANCED_TILEBLIT
+	if (info->tileops)
+		p->dispsw = &tile_switch;
+	else 
+#endif
+		p->dispsw = &accel_switch;
+
 	if (con != fg_console || (info->flags & FBINFO_FLAG_MODULE) ||
 	    info->fix.type == FB_TYPE_TEXT)
 		logo = 0;
@@ -880,7 +758,7 @@
 			vc_resize(con, nr_cols, nr_rows);
 		else if (CON_IS_VISIBLE(vc) &&
 			 vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
-			accel_clear_margins(vc, p, 0);
+			p->dispsw->clear_margins(vc, p, 0);
 			update_screen(con);
 		}
 		if (save) {
@@ -977,11 +855,11 @@
 	y_break = p->vrows - p->yscroll;
 	if (sy < y_break && sy + height - 1 >= y_break) {
 		u_int b = y_break - sy;
-		accel_clear(vc, p, real_y(p, sy), sx, b, width);
-		accel_clear(vc, p, real_y(p, sy + b), sx, height - b,
+		p->dispsw->clear(vc, p, real_y(p, sy), sx, b, width);
+		p->dispsw->clear(vc, p, real_y(p, sy + b), sx, height - b,
 				 width);
 	} else
-		accel_clear(vc, p, real_y(p, sy), sx, height, width);
+		p->dispsw->clear(vc, p, real_y(p, sy), sx, height, width);
 
 	if (redraw_cursor)
 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
@@ -991,10 +869,6 @@
 static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
 {
 	struct display *p = &fb_display[vc->vc_num];
-	struct fb_info *info = p->fb_info;
-	unsigned short charmask = p->charmask;
-	unsigned int width = ((vc->vc_font.width + 7) >> 3);
-	struct fb_image image;
 	int redraw_cursor = 0;
 
 	if (!p->can_soft_blank && console_blanked)
@@ -1008,16 +882,7 @@
 		redraw_cursor = 1;
 	}
 
-	image.fg_color = attr_fgcol(p, c);
-	image.bg_color = attr_bgcol(p, c);
-	image.dx = xpos * vc->vc_font.width;
-	image.dy = real_y(p, ypos) * vc->vc_font.height;
-	image.width = vc->vc_font.width;
-	image.height = vc->vc_font.height;
-	image.depth = 1;
-	image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
-
-	info->fbops->fb_imageblit(info, &image);
+	p->dispsw->putc(vc, p, c, real_y(p, ypos), xpos);
 
 	if (redraw_cursor)
 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
@@ -1042,7 +907,7 @@
 		cursor_undrawn();
 		redraw_cursor = 1;
 	}
-	accel_putcs(vc, p, s, count, real_y(p, ypos), xpos);
+	p->dispsw->putcs(vc, p, s, count, real_y(p, ypos), xpos);
 	if (redraw_cursor)
 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 }
@@ -1070,7 +935,7 @@
 
 	cursor_on = 0;
 	if (cursor_drawn)
-		accel_cursor(p, 0, p->cursor_x,
+		fb_cursor(p, 0, p->cursor_x,
 				  real_y(p, p->cursor_y));
 
 	p->cursor_x = vc->vc_x;
@@ -1084,7 +949,7 @@
 	case CM_MOVE:
 	case CM_DRAW:
 		if (cursor_drawn)
-			accel_cursor(p, FB_CUR_SETCUR, p->cursor_x,
+			fb_cursor(p, FB_CUR_SETCUR, p->cursor_x,
 					  real_y(p, p->cursor_y));
 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 		cursor_on = 1;
@@ -1106,7 +971,7 @@
 		flag = 0;
 		if (!cursor_drawn)
 			flag = FB_CUR_SETCUR;
-		accel_cursor(p, flag, p->cursor_x,
+		fb_cursor(p, flag, p->cursor_x,
 				  real_y(p, p->cursor_y));
 		cursor_drawn ^= 1;
 		vbl_cursor_cnt = cursor_blink_rate;
@@ -1168,7 +1033,7 @@
 
 	p->yscroll += count;
 	if (p->yscroll > p->vrows - vc->vc_rows) {
-		accel_bmove(p, p->vrows - vc->vc_rows, 0, 0, 0,
+		p->dispsw->bmove(p, p->vrows - vc->vc_rows, 0, 0, 0,
 				 vc->vc_rows, vc->vc_cols);
 		p->yscroll -= p->vrows - vc->vc_rows;
 	}
@@ -1176,7 +1041,7 @@
 	info->var.yoffset = p->yscroll * vc->vc_font.height;
 	info->var.vmode &= ~FB_VMODE_YWRAP;
 	update_var(vc->vc_num, info);
-	accel_clear_margins(vc, p, 1);
+	p->dispsw->clear_margins(vc, p, 1);
 	scrollback_max += count;
 	if (scrollback_max > scrollback_phys_max)
 		scrollback_max = scrollback_phys_max;
@@ -1191,7 +1056,7 @@
 
 	p->yscroll -= count;
 	if (p->yscroll < 0) {
-		accel_bmove(p, 0, 0, p->vrows - vc->vc_rows, 0,
+		p->dispsw->bmove(p, 0, 0, p->vrows - vc->vc_rows, 0,
 				 vc->vc_rows, vc->vc_cols);
 		p->yscroll += p->vrows - vc->vc_rows;
 	}
@@ -1199,7 +1064,7 @@
 	info->var.yoffset = p->yscroll * vc->vc_font.height;
 	info->var.vmode &= ~FB_VMODE_YWRAP;
 	update_var(vc->vc_num, info);
-	accel_clear_margins(vc, p, 1);
+	p->dispsw->clear_margins(vc, p, 1);
 	scrollback_max -= count;
 	if (scrollback_max < 0)
 		scrollback_max = 0;
@@ -1265,7 +1130,7 @@
 			if (attr != (c & 0xff00)) {
 				attr = c & 0xff00;
 				if (s > start) {
-					accel_putcs(vc, p, start,
+					p->dispsw->putcs(vc, p, start,
 							 s - start,
 							 real_y(p, line),
 							 x);
@@ -1275,7 +1140,7 @@
 			}
 			if (c == scr_readw(d)) {
 				if (s > start) {
-					accel_putcs(vc, p, start,
+					p->dispsw->putcs(vc, p, start,
 							 s - start,
 							 real_y(p, line),
 							 x);
@@ -1290,7 +1155,7 @@
 			d++;
 		} while (s < le);
 		if (s > start)
-			accel_putcs(vc, p, start, s - start,
+			p->dispsw->putcs(vc, p, start, s - start,
 					 real_y(p, line), x);
 		line++;
 		if (d == (u16 *) softback_end)
@@ -1323,7 +1188,7 @@
 			if (attr != (c & 0xff00)) {
 				attr = c & 0xff00;
 				if (s > start) {
-					accel_putcs(vc, p, start,
+					p->dispsw->putcs(vc, p, start,
 							 s - start,
 							 real_y(p, line),
 							 x);
@@ -1333,7 +1198,7 @@
 			}
 			if (c == scr_readw(d)) {
 				if (s > start) {
-					accel_putcs(vc, p, start,
+					p->dispsw->putcs(vc, p, start,
 							 s - start,
 							 real_y(p, line),
 							 x);
@@ -1350,7 +1215,7 @@
 			d++;
 		} while (s < le);
 		if (s > start)
-			accel_putcs(vc, p, start, s - start,
+			p->dispsw->putcs(vc, p, start, s - start,
 					 real_y(p, line), x);
 		console_conditional_schedule();
 		if (offset > 0)
@@ -1420,9 +1285,9 @@
 			goto redraw_up;
 		switch (p->scrollmode & __SCROLL_YMASK) {
 		case __SCROLL_YMOVE:
-			accel_bmove(p, t + count, 0, t, 0,
+			p->dispsw->bmove(p, t + count, 0, t, 0,
 					 b - t - count, vc->vc_cols);
-			accel_clear(vc, p, b - count, 0, count,
+			p->dispsw->clear(vc, p, b - count, 0, count,
 					 vc->vc_cols);
 			break;
 
@@ -1471,7 +1336,7 @@
 		      redraw_up:
 			fbcon_redraw(vc, p, t, b - t - count,
 				     count * vc->vc_cols);
-			accel_clear(vc, p, real_y(p, b - count), 0,
+			p->dispsw->clear(vc, p, real_y(p, b - count), 0,
 					 count, vc->vc_cols);
 			scr_memsetw((unsigned short *) (vc->vc_origin +
 							vc->vc_size_row *
@@ -1487,9 +1352,9 @@
 			count = vc->vc_rows;
 		switch (p->scrollmode & __SCROLL_YMASK) {
 		case __SCROLL_YMOVE:
-			accel_bmove(p, t, 0, t + count, 0,
+			p->dispsw->bmove(p, t, 0, t + count, 0,
 					 b - t - count, vc->vc_cols);
-			accel_clear(vc, p, t, 0, count, vc->vc_cols);
+			p->dispsw->clear(vc, p, t, 0, count, vc->vc_cols);
 			break;
 
 		case __SCROLL_YWRAP:
@@ -1536,7 +1401,7 @@
 		      redraw_down:
 			fbcon_redraw(vc, p, b - 1, b - t - count,
 				     -count * vc->vc_cols);
-			accel_clear(vc, p, real_y(p, t), 0, count,
+			p->dispsw->clear(vc, p, real_y(p, t), 0, count,
 					 vc->vc_cols);
 			scr_memsetw((unsigned short *) (vc->vc_origin +
 							vc->vc_size_row *
@@ -1615,7 +1480,7 @@
 		}
 		return;
 	}
-	accel_bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height,
+	p->dispsw->bmove(p, real_y(p, sy), sx, real_y(p, dy), dx, height,
 			 width);
 }
 
@@ -1643,8 +1508,8 @@
 		DPRINTK("resize now %ix%i\n", var.xres, var.yres);
 		var.activate = FB_ACTIVATE_NOW;
 		fb_set_var(&var, info);
-		p->vrows = info->var.yres_virtual/fh;
 	}
+	p->vrows = info->var.yres_virtual/fh;
 	return 0;
 }
 
@@ -1654,6 +1519,13 @@
 	struct display *p = &fb_display[unit];
 	struct fb_info *info = p->fb_info;
 
+#ifdef CONFIG_FBCON_ADVANCED_TILEBLIT
+	if (info->tileops)
+		p->dispsw = &tile_switch;
+	else
+#endif
+		p->dispsw = &accel_switch;
+
 	if (softback_top) {
 		int l = fbcon_softback_size / vc->vc_size_row;
 		if (softback_lines)
@@ -1679,6 +1551,9 @@
 	}
 	if (info)
 		info->var.yoffset = p->yscroll = 0;
+
+        fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
+
 	switch (p->scrollmode & __SCROLL_YMASK) {
 	case __SCROLL_YWRAP:
 		scrollback_phys_max = p->vrows - vc->vc_rows;
@@ -1695,14 +1570,39 @@
 	scrollback_max = 0;
 	scrollback_current = 0;
 
+#ifdef CONFIG_FBCON_ADVANCED_TILEBLIT
+	if (info->tileops) {
+		struct fb_tiledata tile;
+		int err, cnt, size;
+		u8 *tiledata;
+
+		cnt = FNTCHARCNT(p->fontdata);
+		if (!cnt)
+			cnt = 256;
+		size = vc->vc_font.height * ((vc->vc_font.width + 7)/8) * cnt; 
+		tiledata = kmalloc(size, GFP_KERNEL);
+		if (tiledata == NULL)
+			return 0;
+		memcpy(tiledata, p->fontdata, size);
+		tile.tile.width = vc->vc_font.width;
+		tile.tile.height = vc->vc_font.height;
+		tile.tile.depth = 1;
+		tile.len = cnt;
+		tile.data = tiledata; 
+		err = info->tileops->fb_loadtiles(info, &tile);
+		kfree(tiledata);
+
+		if (err) return 0;
+	}
+#endif
+
 	info->currcon = unit;
 	
-        fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
 	update_var(unit, info);
 	fbcon_set_palette(vc, color_table); 	
 
 	if (vt_cons[unit]->vc_mode == KD_TEXT)
-		accel_clear_margins(vc, p, 0);
+		p->dispsw->clear_margins(vc, p, 0);
 	if (logo_shown == -2) {
 		logo_shown = fg_console;
 		/* This is protected above by initmem_freed */
@@ -1737,18 +1637,18 @@
 			height = vc->vc_rows;
 			y_break = p->vrows - p->yscroll;
 			if (height > y_break) {
-				accel_clear(vc, p,
+				p->dispsw->clear(vc, p,
 						 real_y(p, 0), 0,
 						 y_break,
 						 vc->vc_cols);
-				accel_clear(vc, p,
+				p->dispsw->clear(vc, p,
 						 real_y(p,
 						y_break),
 						0,
 						 height - y_break,
 						 vc->vc_cols);
 			} else
-				accel_clear(vc, p,
+				p->dispsw->clear(vc, p,
 						 real_y(p, 0), 0,
 						 height,
 						 vc->vc_cols);
@@ -1913,6 +1813,29 @@
 
 	}
 
+#ifdef CONFIG_FBCON_ADVANCED_TILEBLIT
+	if (info->tileops) {
+		struct fb_tiledata tile;
+		int err, size;
+		u8 *tiledata;
+		
+		size = vc->vc_font.height * ((vc->vc_font.width + 7)/8) * cnt; 
+		tiledata = kmalloc(size, GFP_KERNEL);
+		if (tiledata == NULL)
+			return 1;
+		memcpy(tiledata, p->fontdata, size);
+		tile.tile.width = vc->vc_font.width;
+		tile.tile.height = vc->vc_font.height;
+		tile.tile.depth = 1;
+		tile.len = cnt;
+		tile.data = tiledata;
+		
+		err = info->tileops->fb_loadtiles(info, &tile);
+		kfree(tiledata);
+		if (err) return err;
+	}
+#endif
+
 	if (resize) {
 		/* reset wrap/pan */
 		info->var.xoffset = info->var.yoffset = p->yscroll = 0;
@@ -1935,7 +1858,7 @@
 		}
 	} else if (CON_IS_VISIBLE(vc)
 		   && vt_cons[vc->vc_num]->vc_mode == KD_TEXT) {
-		accel_clear_margins(vc, p, 0);
+		p->dispsw->clear_margins(vc, p, 0);
 		update_screen(vc->vc_num);
 	}
 
diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon.h linux-2.5.61/drivers/video/console/fbcon.h
--- linux-2.5.61-fbdev/drivers/video/console/fbcon.h	2003-02-22 02:34:26.000000000 +0000
+++ linux-2.5.61/drivers/video/console/fbcon.h	2003-02-23 06:45:15.000000000 +0000
@@ -46,6 +46,20 @@
     unsigned int fontwidthmask;      /* 1 at (1 << (width - 1)) if width is supported */
 };
 
+struct display_switch {
+	void (*bmove)(struct display *p, int sy, int sx, 
+		      int dy, int dx, int height, int width);
+	void (*clear)(struct vc_data *vc, struct display *p, int sy,
+		      int sx, int height, int width);
+	void (*putcs)(struct vc_data *vc, struct display *p,
+		      const unsigned short *s, int count, 
+		      int yy, int xx);
+	void (*putc)(struct vc_data *vc, struct display *p, 
+		     int c, int ypos, int xpos);
+	void (*clear_margins)(struct vc_data *vc, struct display *p,
+			      int bottom_only);
+};
+
 /* drivers/video/console/fbcon.c */
 extern struct display fb_display[MAX_NR_CONSOLES];
 extern char con2fb_map[MAX_NR_CONSOLES];
@@ -120,5 +134,7 @@
 #define SCROLL_YNOPARTIAL	__SCROLL_YNOPARTIAL
 
 extern int fb_console_init(void);
+extern struct display_switch tile_switch;
+extern struct display_switch accel_switch;
 
 #endif /* _VIDEO_FBCON_H */
diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon_accelops.c linux-2.5.61/drivers/video/console/fbcon_accelops.c
--- linux-2.5.61-fbdev/drivers/video/console/fbcon_accelops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.5.61/drivers/video/console/fbcon_accelops.c	2003-02-23 07:08:50.000000000 +0000
@@ -0,0 +1,229 @@
+/*
+ *  linux/drivers/video/fbcon_defops.c -- Console Ops using Classic Blitting
+ *
+ *	Copyright (C) 2003 James Simmons
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fb.h>
+#include "fbcon.h"
+
+static __inline__ int real_y(struct display *p, int ypos)
+{
+	int rows = p->vrows;
+
+	ypos += p->yscroll;
+	return ypos < rows ? ypos : ypos - rows;
+}
+
+/*
+ * Accelerated handlers.
+ */
+static void accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
+			int height, int width)
+{
+	struct fb_info *info = p->fb_info;
+	struct vc_data *vc = p->conp;
+	struct fb_copyarea area;
+
+	area.sx = sx * vc->vc_font.width;
+	area.sy = sy * vc->vc_font.height;
+	area.dx = dx * vc->vc_font.width;
+	area.dy = dy * vc->vc_font.height;
+	area.height = height * vc->vc_font.height;
+	area.width = width * vc->vc_font.width;
+
+	info->fbops->fb_copyarea(info, &area);
+}
+
+static void accel_clear(struct vc_data *vc, struct display *p, int sy,
+			int sx, int height, int width)
+{
+	struct fb_info *info = p->fb_info;
+	struct fb_fillrect region;
+
+	region.color = attr_bgcol_ec(p, vc);
+	region.dx = sx * vc->vc_font.width;
+	region.dy = sy * vc->vc_font.height;
+	region.width = width * vc->vc_font.width;
+	region.height = height * vc->vc_font.height;
+	region.rop = ROP_COPY;
+
+	info->fbops->fb_fillrect(info, &region);
+}	
+
+static void accel_putc(struct vc_data *vc, struct display *p,
+		       int c, int ypos, int xpos)
+{
+	struct fb_info *info = p->fb_info;
+	unsigned short charmask = p->charmask;
+	unsigned int width = ((vc->vc_font.width + 7) >> 3);
+	struct fb_image image;
+
+	image.dx = xpos * vc->vc_font.width;
+	image.dy = real_y(p, ypos) * vc->vc_font.height;
+	image.width = vc->vc_font.width;
+	image.height = vc->vc_font.height;
+	image.fg_color = attr_fgcol(p, c);
+	image.bg_color = attr_bgcol(p, c);
+	image.depth = 0;
+	image.data = p->fontdata + (c & charmask) * vc->vc_font.height * width;
+
+	info->fbops->fb_imageblit(info, &image);
+}
+
+#define FB_PIXMAPSIZE 8192
+static void putcs_unaligned(struct vc_data *vc, struct display *p,
+			    struct fb_info *info, struct fb_image *image, 
+			    int count, const unsigned short *s)
+{
+	unsigned int width = (vc->vc_font.width + 7)/8;
+	unsigned int cellsize = vc->vc_font.height * width;
+	unsigned int maxcnt = FB_PIXMAPSIZE/cellsize;
+	unsigned int pitch, cnt, i, j, k;
+	unsigned int shift_low = 0, mod = vc->vc_font.width % 8;
+	unsigned int shift_high = 8;
+	unsigned int idx = vc->vc_font.width/8;
+	unsigned short charmask = p->charmask;
+	u8 mask, *src, *dst, *dst0;
+	
+	while (count) {
+		if (count > maxcnt) 
+			cnt = k = maxcnt;
+		else
+			cnt = k = count;
+		
+		dst0 = (u8 *) image->data;
+		image->width = vc->vc_font.width * cnt;
+		pitch = (image->width + 7)/8;
+		while (k--) {
+			src = p->fontdata + (scr_readw(s++) & charmask) * cellsize;
+			dst = dst0;
+			mask = (u8) (0xfff << shift_high);
+			for (i = image->height; i--; ) {
+				for (j = 0; j < idx; j++) {
+					dst[j] &= mask;
+					dst[j] |= *src >> shift_low;
+					dst[j+1] = *src << shift_high;
+					src++;
+				}
+				dst[idx] &= mask;
+				dst[idx] |= *src++ >> shift_low;
+				dst += pitch;
+			}
+			shift_low += mod;
+			shift_low &= 7;
+			shift_high = 8 - shift_low;
+			dst0 += (shift_low) ? width - 1 : width;
+		}
+		
+		info->fbops->fb_imageblit(info, image);
+		image->dx += cnt * vc->vc_font.width;
+		count -= cnt;
+	}
+}
+
+static void putcs_aligned(struct vc_data *vc, struct display *p,
+			  struct fb_info *info, struct fb_image *image, 
+			  int count, const unsigned short *s)
+{
+	unsigned int width = (vc->vc_font.width + 7)/8;
+	unsigned int cellsize = vc->vc_font.height * width;
+	unsigned int maxcnt = FB_PIXMAPSIZE/cellsize;
+	unsigned int pitch, cnt, i, j, k;
+	unsigned short charmask = p->charmask;
+	u8 *src, *dst, *dst0;
+
+	while (count) {
+		if (count > maxcnt)
+			cnt = k = maxcnt;
+		else
+			cnt = k = count;
+		dst0 = (u8 *) image->data;
+		pitch = width *cnt;
+		image->width = vc->vc_font.width * cnt;
+		while (k--) {
+			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);
+		image->dx += cnt * vc->vc_font.width;
+		count -= cnt;
+	}
+}
+
+static void accel_putcs(struct vc_data *vc, struct display *p,
+			const unsigned short *s, int count, int yy, int xx)
+{
+	static u8 pixmap[FB_PIXMAPSIZE];
+	struct fb_info *info = p->fb_info;
+	struct fb_image image;
+	u16 c = scr_readw(s);
+	
+	image.fg_color = attr_fgcol(p, c);
+	image.bg_color = attr_bgcol(p, c);
+	image.dx = xx * vc->vc_font.width;
+	image.dy = yy * vc->vc_font.height;
+	image.height = vc->vc_font.height;
+	image.depth = 0;
+	image.data = pixmap;
+
+	if (!(vc->vc_font.width & 7)) 
+		putcs_aligned(vc, p, info, &image, count, s);
+	else 
+		putcs_unaligned(vc, p, info, &image, count, s);
+}
+
+static void accel_clear_margins(struct vc_data *vc, struct display *p,
+				int bottom_only)
+{
+	struct fb_info *info = p->fb_info;
+	unsigned int cw = vc->vc_font.width;
+	unsigned int ch = vc->vc_font.height;
+	unsigned int rw = info->var.xres % cw;
+	unsigned int bh = info->var.yres % ch;
+	unsigned int rs = info->var.xres - rw;
+	unsigned int bs = info->var.yres - bh;
+	struct fb_fillrect region;
+
+	region.color = attr_bgcol_ec(p, vc);
+	region.rop = ROP_COPY;
+
+	if (rw & !bottom_only) {
+		region.dx = info->var.xoffset + rs;
+		region.dy = 0;
+		region.width = rw;
+		region.height = info->var.yres_virtual;
+		info->fbops->fb_fillrect(info, &region);
+	}
+
+	if (bh) {
+		region.dx = info->var.xoffset;
+		region.dy = info->var.yoffset + bs;
+		region.width = rs;
+		region.height = bh;
+		info->fbops->fb_fillrect(info, &region);
+	}	
+}	
+
+struct display_switch accel_switch = {
+	.bmove =         accel_bmove,
+	.clear =         accel_clear,
+	.putc =          accel_putc,
+	.putcs =         accel_putcs,
+	.clear_margins = accel_clear_margins,
+};
+
+EXPORT_SYMBOL(accel_switch);
diff -Naur linux-2.5.61-fbdev/drivers/video/console/fbcon_tileops.c linux-2.5.61/drivers/video/console/fbcon_tileops.c
--- linux-2.5.61-fbdev/drivers/video/console/fbcon_tileops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.5.61/drivers/video/console/fbcon_tileops.c	2003-02-23 06:42:26.000000000 +0000
@@ -0,0 +1,118 @@
+/*
+ *  linux/drivers/video/fbcon_tileops.c -- Console Ops using Tile Blitting
+ *                                         (ie. Text Mode support)
+ *
+ *	Copyright (C) 2003 James Simmons
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License.  See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/fb.h>
+#include "fbcon.h"
+
+static void tile_bmove(struct display *p, int sy, int sx, int dy, int dx,
+		       int height, int width)
+{
+	struct fb_info *info = p->fb_info;
+	struct fb_tilecopy tilerect;
+
+	tilerect.sx = sx;
+	tilerect.sy = sy;
+	tilerect.dx = dx;
+	tilerect.dy = dy;
+	tilerect.height = height;
+	tilerect.width = width;
+	
+	info->tileops->fb_tilecopy(info, &tilerect);
+}
+
+static void tile_clear(struct vc_data *vc, struct display *p, int sy,
+		       int sx, int height, int width)
+{
+	struct fb_info *info = p->fb_info;
+	struct fb_tilefill tilerect;
+	
+	tilerect.dx = sx;
+	tilerect.dy = sy;
+	tilerect.width = width;
+	tilerect.height = height;
+	tilerect.fg_color = attr_fgcol_ec(p, vc);
+	tilerect.bg_color = attr_bgcol_ec(p, vc);
+	tilerect.idx = vc->vc_video_erase_char & p->charmask;
+	tilerect.rop = ROP_COPY;
+
+	info->tileops->fb_tilefill(info, &tilerect);
+}
+
+static void tile_putc(struct vc_data *vc, struct display *p,
+		      int c, int ypos, int xpos)
+{
+	struct fb_info *info = p->fb_info;
+	struct fb_tileblit tilerect;
+	u32 font = c & p->charmask;
+	
+	tilerect.dx = xpos;
+	tilerect.dy = ypos;
+	tilerect.width = 1;
+	tilerect.height = 1;
+	tilerect.fg_color = attr_fgcol(p, c);
+	tilerect.bg_color = attr_bgcol(p, c);
+	tilerect.data = &font;
+
+	info->tileops->fb_tileblit(info, &tilerect);
+}
+
+#define TILEMAP_SIZE 1024
+static void tile_putcs(struct vc_data *vc, struct display *p,
+			const unsigned short *s, int count, 
+			int yy, int xx)
+{
+	static u32 tilemap[TILEMAP_SIZE];
+	struct fb_info *info = p->fb_info;
+	struct fb_tileblit tilerect;
+	int maxcnt = TILEMAP_SIZE, i, cnt;
+	u16 c = scr_readw(s);
+
+	tilerect.dx = xx;
+	tilerect.dy = yy;
+	tilerect.height = 1;
+	tilerect.fg_color = attr_fgcol(p, c);
+	tilerect.bg_color = attr_bgcol(p, c);
+	tilerect.data = tilemap;
+
+	while (count) {
+		cnt = (count > maxcnt) ? maxcnt : count;
+		tilerect.width = cnt;
+		for (i = 0; i < cnt; i++) 
+			tilemap[i] = (u32) (scr_readw(s++) & p->charmask);
+		
+		info->tileops->fb_tileblit(info, &tilerect);
+		tilerect.dx += cnt;
+		count -= cnt;
+	}
+}
+
+static void tile_clear_margins(struct vc_data *vc, struct display *p,
+			       int bottom_only)
+{
+	/* Not used */
+	return;
+}
+
+struct display_switch tile_switch = {
+	.bmove =         tile_bmove,
+	.clear =         tile_clear,
+	.putc  =         tile_putc,
+	.putcs =         tile_putcs,
+	.clear_margins = tile_clear_margins,
+};
+
+EXPORT_SYMBOL(tile_switch);
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>, "
+	      "Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Console Tile Blitting Ops");
+MODULE_LICENSE("GPL");
diff -Naur linux-2.5.61-fbdev/drivers/video/fbmem.c linux-2.5.61/drivers/video/fbmem.c
--- linux-2.5.61-fbdev/drivers/video/fbmem.c	2003-02-22 02:34:26.000000000 +0000
+++ linux-2.5.61/drivers/video/fbmem.c	2003-02-23 06:42:26.000000000 +0000
@@ -363,14 +363,14 @@
 static int ofonly __initdata = 0;
 #endif
 
+#ifdef CONFIG_LOGO
+#include <linux/linux_logo.h>
+
 static inline unsigned safe_shift(unsigned d, int n)
 {
 	return n < 0 ? d >> -n : d << n;
 }
 
-#ifdef CONFIG_FB_LOGO
-#include <linux/linux_logo.h>
-
 static void __init fb_set_logocmap(struct fb_info *info,
 				   const struct linux_logo *logo)
 {
diff -Naur linux-2.5.61-fbdev/include/linux/fb.h linux-2.5.61/include/linux/fb.h
--- linux-2.5.61-fbdev/include/linux/fb.h	2003-02-22 02:34:26.000000000 +0000
+++ linux-2.5.61/include/linux/fb.h	2003-02-23 06:42:26.000000000 +0000
@@ -380,6 +380,77 @@
     int (*fb_mmap)(struct fb_info *info, struct file *file, struct vm_area_struct *vma);
 };
 
+/* 
+ * Tile Blitting Support
+ * 
+ * In Tile Blitting, the basic unit is a Tile which is a bitmap with
+ * a predefined width and height, and optionally, other properties
+ * such as color depth, spacing, transparency,  etc.  For now, we'll 
+ * just support width, height, and color depth.
+ * 
+ * All operations are analogous to classic blitting operations which
+ * use pixels as the basic unit.  Instead of pixels, it will use tiles,
+ * instead of info->pseudo_palette, it will use tiledata, etc.
+ */
+
+struct fb_tile {
+	__u32 width;            /* tile width in pixels */
+	__u32 height;           /* tile height in scanlines */
+	__u32 depth;            /* pixel depth */
+};
+
+struct fb_tiledata {
+	struct fb_tile tile;    /* tile properties */
+	__u32 len;              /* number of tiles in the map */
+	__u8  *data;            /* packed tile data */
+};
+
+struct fb_tileblit {
+	__u32 dx;               /* destination x origin, in tiles */
+	__u32 dy;               /* destination y origin, in tiles */
+	__u32 width;            /* destination window width, in tiles */
+	__u32 height;           /* destination window height, in tiles */
+	__u32 fg_color;         /* fg_color if monochrome */
+	__u32 bg_color;         /* bg_color if monochrome */
+	__u32 *data;            /* tile map - array of indices to tiledata */
+};
+
+struct fb_tilecopy {
+	__u32 dx;               /* destination window origin... */
+	__u32 dy;               /* in tiles */
+	__u32 width;            /* destination width, in tiles */
+	__u32 height;           /* destination height, in tiles */
+	__u32 sx;               /* source window origin ... */
+	__u32 sy;               /* in tiles */
+};
+
+struct fb_tilefill {
+	__u32 dx;               /* destination window origin ... */
+	__u32 dy;               /* in tiles */
+	__u32 width;            /* destination width in tiles */
+	__u32 height;           /* destination height in tiles */
+	__u32 fg_color;         /* fg_color if monochrome */
+	__u32 bg_color;         /* bg_color if monochrome */
+	__u32 rop;              /* rop operation */
+	__u32 idx;              /* index to current tiledata */
+};
+
+struct fb_tileops {
+    /* upload tile data to driver and make it current... the driver
+     * must copy the contents of tiledata.data, not just the pointer to it */
+    int (*fb_loadtiles)(struct fb_info *info, 
+			const struct fb_tiledata *tileinfo);
+    /* blit tiles to destination from a tilemap */
+    void (*fb_tileblit)(struct fb_info *info, 
+			const struct fb_tileblit *tilemap);
+    /* copy tiles from one region of fb memory to another */
+    void (*fb_tilecopy)(struct fb_info *info, const struct fb_tilecopy *area);
+    /* fill a region of fb memory with a tile */
+    void (*fb_tilefill)(struct fb_info *info, 
+			const struct fb_tilefill *region);
+    /* If driver is to support tile blitting, all hooks above are required */
+};
+
 struct fb_info {
    kdev_t node;
    int flags;
@@ -391,6 +462,7 @@
    struct fb_cursor cursor;		/* Current cursor */	
    struct fb_cmap cmap;                 /* Current cmap */
    struct fb_ops *fbops;
+   struct fb_tileops *tileops;          /* Tile blitting */
    char *screen_base;                   /* Virtual address */
    struct vc_data *display_fg;		/* Console visible on this display */
    int currcon;				/* Current VC. */	

  reply	other threads:[~2003-02-23  7:42 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-02-23  4:42 [PATCH] Tile Blitting Antonino Daplas
2003-02-23  7:43 ` Antonino Daplas [this message]
2003-02-23 11:07   ` Antonino Daplas
2003-02-26 20:11     ` James Simmons
2003-02-27  0:35       ` Antonino Daplas
2003-02-27  1:18         ` James Simmons
2003-02-27 14:15           ` Antonino Daplas
2003-02-27 18:25             ` Michel Dänzer
2003-02-27 19:48               ` James Simmons
2003-03-02 12:14                 ` Geert Uytterhoeven
2003-03-03 21:32                   ` Antonino Daplas
2003-02-27 21:47               ` Antonino Daplas

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=1045986190.1189.2.camel@localhost.localdomain \
    --to=adaplas@pol.net \
    --cc=jsimmons@infradead.org \
    --cc=linux-fbdev-devel@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).