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, ®ion);
-}
-
-#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, ®ion);
- }
-
- if (bh) {
- region.dx = info->var.xoffset;
- region.dy = info->var.yoffset + bs;
- region.width = rs;
- region.height = bh;
- info->fbops->fb_fillrect(info, ®ion);
- }
-}
-
-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, ®ion);
+}
+
+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, ®ion);
+ }
+
+ if (bh) {
+ region.dx = info->var.xoffset;
+ region.dy = info->var.yoffset + bs;
+ region.width = rs;
+ region.height = bh;
+ info->fbops->fb_fillrect(info, ®ion);
+ }
+}
+
+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. */
next prev parent 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).