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

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

Hi James,

If fbcon will support different methods of rasterizing to the
framebuffer, it's best if display->dispsw is revived.  Currently, fbcon
supports classic blitting, but if you decide to add text mode support
(for matroxfb and sbusfb), then tile blitting needs to be supported
too.  Also, rotation will require another method, and so will texture
mapping if you ever decide to add this (Isn't this a bit overkill?!). 
The struct display is not visible to the drivers, so fbcon need to know
which dispsw to use, possibly based on a new field in struct fb_info or
the presence of the function pointer. I prefer an info->caps field so
drivers need not mangle function pointers.

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.

The second patch adds generic tile blitting operation, to be used only
for testing purposes since it's very slow.  It just wraps fb_imageblit
and fb_copyarea.  If anyone wants to test this, just link the driver
cfb_tileops.o, add "info->tileops = &cfb_tileops" during driver
initialization, and enable Tile Blitting support in the kernel.  

Tony

PS: reverse the "accel_putcs() optimazation patch" if applied



[-- Attachment #2: tileblit1.diff --]
[-- Type: text/x-patch, Size: 27737 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 03:19:44.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 03:19:48.000000000 +0000
@@ -16,6 +16,12 @@
 
 font-objs += $(font-objs-y)
 
+fbcon_adv-obj := fbadv.o
+
+fbcon_adv-obj-$(CONFIG_FBCON_ADVANCED_TILEBLIT) += fbcon_tileops.o
+
+fbcon_adv-objs += $(fbcon_adv-obj-y)
+
 # Each configuration option enables a list of files.
 
 obj-$(CONFIG_DUMMY_CONSOLE)       += dummycon.o
@@ -24,7 +30,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 03:56:01.000000000 +0000
@@ -331,17 +331,120 @@
 	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)
+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)/8);
+	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);
-	static u8 pixmap[FB_PIXMAPSIZE];
 	
 	image.fg_color = attr_fgcol(p, c);
 	image.bg_color = attr_bgcol(p, c);
@@ -349,47 +452,12 @@
 	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)) {
-		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;
-		}	
-	}
+	if (!(vc->vc_font.width & 7)) 
+		putcs_aligned(vc, p, info, &image, count, s);
+	else 
+		putcs_unaligned(vc, p, info, &image, count, s);
 }
 
 void accel_clear_margins(struct vc_data *vc, struct display *p,
@@ -424,7 +492,15 @@
 	}	
 }	
 
-void accel_cursor(struct display *p, int flags, int xx, int yy)
+static struct display_switch accel_switch = {
+	.bmove =         accel_bmove,
+	.clear =         accel_clear,
+	.putc =          accel_putc,
+	.putcs =         accel_putcs,
+	.clear_margins = accel_clear_margins,
+};
+
+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 +819,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 +963,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 +1060,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 +1074,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 +1087,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 +1112,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 +1140,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 +1154,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 +1176,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 +1238,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 +1246,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 +1261,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 +1269,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 +1335,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 +1345,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 +1360,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 +1393,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 +1403,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 +1420,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 +1490,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 +1541,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 +1557,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 +1606,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 +1685,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 +1713,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 +1724,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 +1756,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 +1775,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 +1842,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 +2018,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 +2063,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 03:20:58.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,6 @@
 #define SCROLL_YNOPARTIAL	__SCROLL_YNOPARTIAL
 
 extern int fb_console_init(void);
+extern struct display_switch tile_switch;
 
 #endif /* _VIDEO_FBCON_H */
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 03:21:47.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 04:13:57.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 03:19:50.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. */	

[-- Attachment #3: cfb_tileops.diff --]
[-- Type: text/x-patch, Size: 3875 bytes --]

diff -Naur linux-2.5.61-fbdev/cfb_tileops.c linux-2.5.61/cfb_tileops.c
--- linux-2.5.61-fbdev/cfb_tileops.c	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.5.61/cfb_tileops.c	2003-02-23 04:17:36.000000000 +0000
@@ -0,0 +1,130 @@
+/*
+ *  Generic TileBLT function for frame buffer with packed pixels of any depth.
+ *
+ *      Copyright (C)  June 1999 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.
+ *
+ * NOTES:
+ *
+ *  This is a test program to implement Tile Blitting using classical blitting
+ *  routines.  This is naturally slower, so don't use this for your default
+ *  operations.
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+#include <asm/types.h>
+
+static struct fb_tiledata cfb_tileinfo;
+static u8 *cfb_tiledata = NULL;
+
+static int cfb_loadtiles(struct fb_info *info, 
+			 const struct fb_tiledata *tileinfo)
+{
+	u32 size = (tileinfo->tile.width + 7)/8 * tileinfo->tile.height;
+
+	size *= tileinfo->len;
+	if (cfb_tiledata) {
+		if (info->fbops->fb_sync)
+			info->fbops->fb_sync(info);
+		kfree(cfb_tiledata);
+		cfb_tiledata = NULL;
+	}
+			
+	cfb_tiledata = kmalloc(size, GFP_KERNEL);
+	if (cfb_tiledata == NULL)
+		return 1;
+	cfb_tileinfo = *tileinfo;
+	cfb_tileinfo.data = cfb_tiledata;
+	memcpy(cfb_tiledata, tileinfo->data, size);
+
+	return 0;
+}
+
+static void cfb_tileblit(struct fb_info *info, 
+			 const struct fb_tileblit *tilemap)
+{
+	struct fb_image image;
+	u32 width = cfb_tileinfo.tile.width;
+	u32 height = cfb_tileinfo.tile.height;
+	u32 cellsize = (width + 7)/8 * height;
+	int i;
+
+	image.dx = tilemap->dx * width;
+	image.dy = tilemap->dy * height;
+	image.width = width;
+	image.height = tilemap->height * height;
+	image.fg_color = tilemap->fg_color;
+	image.bg_color = tilemap->bg_color;
+	image.depth = 0;
+
+	for (i = 0; i < tilemap->width; i++) {
+		image.data = cfb_tileinfo.data + (tilemap->data[i] * cellsize);
+		info->fbops->fb_imageblit(info, &image);
+		image.dx += width;
+	}
+}
+
+static void cfb_tilefill(struct fb_info *info, 
+			 const struct fb_tilefill *tilerect)
+{
+	struct fb_image image;
+	u32 width = cfb_tileinfo.tile.width;
+	u32 height = cfb_tileinfo.tile.height;
+	u32 dx, dy, i, j;
+
+	dx = tilerect->dx * width;
+	dy = tilerect->dy * height;
+	image.width = width;
+	image.height = height;
+	image.fg_color = tilerect->fg_color;
+	image.bg_color = tilerect->bg_color;
+	image.data = cfb_tileinfo.data + 
+		tilerect->idx * ((width + 7)/8 * height);
+	image.depth = 0;
+
+	for (i = 0; i < tilerect->height; i++) {
+		image.dy = dy;
+		for (j = 0; j < tilerect->width; j++) {
+			image.dx = dx;
+			info->fbops->fb_imageblit(info, &image);
+			dx += width;
+		}
+		dy += height;
+	}
+}
+
+static void cfb_tilecopy(struct fb_info *info, const struct fb_tilecopy *tileregion)
+{
+	struct fb_copyarea area;
+	u32 width = cfb_tileinfo.tile.width;
+	u32 height = cfb_tileinfo.tile.height;
+
+	area.dx = tileregion->dx * width;
+	area.dy = tileregion->dy * height;
+	area.sx = tileregion->sx * width;
+	area.sy = tileregion->sy * height;
+	area.width = tileregion->width * width;
+	area.height = tileregion->height * height;
+
+	info->fbops->fb_copyarea(info, &area);
+}
+
+struct fb_tileops cfb_tileops = {
+	.fb_loadtiles = cfb_loadtiles,
+	.fb_tileblit  = cfb_tileblit,
+	.fb_tilecopy  = cfb_tilecopy,
+	.fb_tilefill  = cfb_tilefill,
+};
+
+EXPORT_SYMBOL(cfb_tileops);
+MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>, "
+	      "Antonino Daplas <adaplas@pol.net>");
+MODULE_DESCRIPTION("Low Level Tile Blitting Ops");
+MODULE_LICENSE("GPL");
+
+ 	

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

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-02-23  4:42 Antonino Daplas [this message]
2003-02-23  7:43 ` [PATCH] Tile Blitting Antonino Daplas
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=1045975269.1676.18.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).