All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.