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: Geert Uytterhoeven <geert@linux-m68k.org>,
	Petr Vandrovec <vandrove@vc.cvut.cz>,
	Linux Fbdev development list
	<linux-fbdev-devel@lists.sourceforge.net>,
	Linux Kernel List <linux-kernel@vger.kernel.org>,
	davidm@redhat.com
Subject: Re: [Linux-fbdev-devel] [PATCH][FBDEV]: fb_putcs() and fb_setfont() methods
Date: 10 Jan 2003 22:36:53 +0800	[thread overview]
Message-ID: <1042209348.1029.43.camel@localhost.localdomain> (raw)
In-Reply-To: <Pine.LNX.4.44.0301090034020.4976-100000@phoenix.infradead.org>

On Fri, 2003-01-10 at 02:09, James Simmons wrote:
> > 
> > So maybe if we can rename fb_putcs() to fb_tileblit(), fb_setfont() to
> > fb_loadtiles(), struct fb_chars to struct fb_tilemap and struct
> > fb_fontdata to struct fb_tiledata, maybe it will be more acceptable?
> > 
> > It can be even be expanded by including fb_tiledata.depth
> > fb_tiledata.cmap so we can support multi-colored tiled blitting.
> 
> This I have no problem with. I'm willing to accept this. As long as data 
> from the console layer is not touched. As for loadtiles one thing I like 
> to address is memory allocation. It probable is good idea to do things 
> like place the tile data in buffers allocated by pci_alloc_consistent.
> The other fear is it will only support so many tiles. 
> 

Hmm, so you're willing to accept this... okay, attached is another
patch, made it a bit cleaner so none of the console data will be ever
touched.  Also expanded it so tile blitting has an equivalent 
counterpart with classic blitting.

Thinking about it, I think tile blitting may one day become useful if
ever the console supports more than 16-colors.  Imagine how expensive it
would be to draw 32-bit fonts using classic blitting.

Tried it with a few test hooks, works fine except for one thing:  the
font is initially scrambled at boot, but became fixed later on.  I don't
know how to fix that.

Tony


diff -Naur linux-2.5.54/drivers/video/console/fbcon.c linux/drivers/video/console/fbcon.c
--- linux-2.5.54/drivers/video/console/fbcon.c	2003-01-10 11:08:04.000000000 +0000
+++ linux/drivers/video/console/fbcon.c	2003-01-10 11:04:59.000000000 +0000
@@ -350,35 +350,91 @@
 {
 	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;
+	if (info->caps & FB_CAPS_TILEBLIT && info->tileops) { 
+		struct fb_tilecopy tilerect;
 
-	info->fbops->fb_copyarea(info, &area);
+		tilerect.sx = sx;
+		tilerect.sy = sy;
+		tilerect.dx = dx;
+		tilerect.dy = dy;
+		tilerect.width = width;
+		tilerect.height = height;
+
+		info->tileops->fb_tilecopy(info, &tilerect);
+	} else { 
+		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;
+	if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {  
+		struct fb_tilefill tilerect;
 
-	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;
+		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->fbops->fb_fillrect(info, &region);
-}	
+		info->tileops->fb_tilefill(info, &tilerect);
+	} else {
+		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
+static void tile_putcs(struct vc_data *vc, struct display *p, u32 *tilemap,
+		       const unsigned short *s, int count, int yy, int xx)
+{
+	struct fb_info *info = p->fb_info;
+	struct fb_tileblit tilerect;
+	int maxcnt = FB_PIXMAPSIZE/4, 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;
+	}
+}
+
 void accel_putcs(struct vc_data *vc, struct display *p,
 			const unsigned short *s, int count, int yy, int xx)
 {
@@ -390,6 +446,11 @@
 	u16 c = scr_readw(s);
 	static u8 pixmap[FB_PIXMAPSIZE];
 	
+	if (info->caps & FB_CAPS_TILEBLIT && info->tileops) { 
+		tile_putcs(vc, p, (u32 *) pixmap, s, count, yy, xx);
+		return;
+	}
+
 	image.fg_color = attr_fgcol(p, c);
 	image.bg_color = attr_bgcol(p, c);
 	image.dx = xx * vc->vc_font.width;
@@ -452,6 +513,10 @@
 	unsigned int bs = info->var.yres - bh;
 	struct fb_fillrect region;
 
+	/* unneeded for tile blits */
+	if (info->caps && FB_CAPS_TILEBLIT && info->tileops)
+		return;
+
 	region.color = attr_bgcol_ec(p, vc);
 	region.rop = ROP_COPY;
 
@@ -1150,7 +1215,6 @@
 	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)
@@ -1164,17 +1228,33 @@
 		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;
+	if (info->caps & FB_CAPS_TILEBLIT && info->tileops) { 
+		struct fb_tileblit tilerect;
+	  
+		u32 font = c & charmask;
+		tilerect.dx = xpos;
+		tilerect.dy = real_y(p, 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);
+	} else {
+		struct fb_image image;
 
-	info->fbops->fb_imageblit(info, &image);
+		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);
+	}
 	if (redraw_cursor)
 		vbl_cursor_cnt = CURSOR_DRAW_DELAY;
 }
@@ -1935,6 +2015,31 @@
 	scrollback_max = 0;
 	scrollback_current = 0;
 
+	if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {
+		struct fb_tiledata tile;
+		int err, cnt = FNTCHARCNT(p->fontdata);
+		int size = (vc->vc_font.height * vc->vc_font.width)/8 * cnt; 
+		u8 *tiledata;
+
+		/*
+		 * make sure we don't allow drivers to mangle
+		 * console fontdata
+		 */
+		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;
+	}
+
 	info->currcon = unit;
 	
         fbcon_resize(vc, vc->vc_cols, vc->vc_rows);
@@ -2152,6 +2257,27 @@
 
 	}
 
+	if (info->caps & FB_CAPS_TILEBLIT && info->tileops) {
+		struct fb_tiledata tile;
+		int size = (vc->vc_font.height * vc->vc_font.width)/8 * cnt; 
+		int err;
+		u8 *tiledata;
+		
+		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;
+	}
+
 	if (resize) {
 		/* reset wrap/pan */
 		info->var.xoffset = info->var.yoffset = p->yscroll = 0;
diff -Naur linux-2.5.54/include/linux/fb.h linux/include/linux/fb.h
--- linux-2.5.54/include/linux/fb.h	2003-01-10 11:08:19.000000000 +0000
+++ linux/include/linux/fb.h	2003-01-10 11:21:27.000000000 +0000
@@ -173,6 +173,10 @@
 #define FB_VMODE_SMOOTH_XPAN	512	/* smooth xpan possible (internally used) */
 #define FB_VMODE_CONUPDATE	512	/* don't update x/yoffset	*/
 
+/* Driver Capability */
+#define FB_CAPS_CLIPPING        1       /* hardware can do clipping */
+#define FB_CAPS_TILEBLIT        2       /* hardware can do tileblits */
+
 #define PICOS2KHZ(a) (1000000000UL/(a))
 #define KHZ2PICOS(a) (1000000000UL/(a))
 
@@ -377,6 +381,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 *tile);
+    /* 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;
@@ -388,6 +463,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. */	

      parent reply	other threads:[~2003-01-10 14:36 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-01-04  9:25 [PATCH][FBDEV]: fb_putcs() and fb_setfont() methods Antonino Daplas
2003-01-04 14:00 ` Jurriaan
2003-01-04 21:08   ` James Simmons
2003-01-04 20:41 ` Petr Vandrovec
2003-01-04 21:12   ` James Simmons
2003-01-04 23:17     ` Petr Vandrovec
2003-01-07 21:46       ` [Linux-fbdev-devel] " James Simmons
2003-01-04 21:07 ` James Simmons
2003-01-04 22:06   ` [Linux-fbdev-devel] " Antonino Daplas
2003-01-07 21:43     ` James Simmons
2003-01-04 23:30   ` [Linux-fbdev-devel] " Petr Vandrovec
2003-01-07 21:51     ` James Simmons
2003-01-08 10:47       ` Geert Uytterhoeven
2003-01-08 18:19         ` Antonino Daplas
2003-01-09 18:09           ` [Linux-fbdev-devel] " James Simmons
2003-01-09 20:54             ` Geert Uytterhoeven
2003-01-09 21:25               ` [Linux-fbdev-devel] " James Simmons
2003-01-10 14:36             ` Antonino Daplas [this message]

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=1042209348.1029.43.camel@localhost.localdomain \
    --to=adaplas@pol.net \
    --cc=davidm@redhat.com \
    --cc=geert@linux-m68k.org \
    --cc=jsimmons@infradead.org \
    --cc=linux-fbdev-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=vandrove@vc.cvut.cz \
    /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).