Module Name: src
Committed By: macallan
Date: Sat Oct 20 13:52:11 UTC 2012
Modified Files:
src/sys/dev/sbus: agten.c files.sbus
Log Message:
- only sync the drawing engine when we're about to access video memory
- use the blitter to draw the cursor
- use the glyphcache to minimize vram access
-> about 15% to 20% speedup
To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/sys/dev/sbus/agten.c
cvs rdiff -u -r1.38 -r1.39 src/sys/dev/sbus/files.sbus
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/sbus/agten.c
diff -u src/sys/dev/sbus/agten.c:1.28 src/sys/dev/sbus/agten.c:1.29
--- src/sys/dev/sbus/agten.c:1.28 Wed Jan 11 16:08:57 2012
+++ src/sys/dev/sbus/agten.c Sat Oct 20 13:52:11 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: agten.c,v 1.28 2012/01/11 16:08:57 macallan Exp $ */
+/* $NetBSD: agten.c,v 1.29 2012/10/20 13:52:11 macallan Exp $ */
/*-
* Copyright (c) 2007 Michael Lorenz
@@ -27,14 +27,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: agten.c,v 1.28 2012/01/11 16:08:57 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: agten.c,v 1.29 2012/10/20 13:52:11 macallan Exp $");
/*
* a driver for the Fujitsu AG-10e SBus framebuffer
*
* this thing is Frankenstein's Monster among graphics boards.
* it contains three graphics chips:
- * a GLint - 24bit stuff, double-buffered
+ * a GLint 300SX - 24bit stuff, double-buffered
* an Imagine 128 which provides an 8bit overlay
* a Weitek P9100 which provides WIDs
* so here we need to mess only with the P9100 and the I128 - for X we just
@@ -68,6 +68,7 @@ __KERNEL_RCSID(0, "$NetBSD: agten.c,v 1.
#include <dev/wsfont/wsfont.h>
#include <dev/wscons/wsdisplay_vconsvar.h>
+#include <dev/wscons/wsdisplay_glyphcachevar.h>
#include <dev/sbus/p9100reg.h>
#include <dev/ic/ibm561reg.h>
@@ -119,7 +120,11 @@ struct agten_softc {
int sc_mode;
uint32_t sc_bg;
+
+ void (*sc_putchar)(void *, int, int, u_int, long);
+
struct vcons_data vd;
+ glyphcache sc_gc;
};
CFATTACH_DECL_NEW(agten, sizeof(struct agten_softc),
@@ -135,6 +140,11 @@ static void agten_gfx(struct agten_softc
static void agten_set_video(struct agten_softc *, int);
static int agten_get_video(struct agten_softc *);
+static void agten_bitblt(void *, int, int, int, int, int, int, int);
+static void agten_rectfill(void *, int, int, int, int, long);
+
+static void agten_putchar(void *, int, int, u_int, long);
+static void agten_cursor(void *, int, int, int);
static void agten_copycols(void *, int, int, int, int);
static void agten_erasecols(void *, int, int, int, long);
static void agten_copyrows(void *, int, int, int);
@@ -236,6 +246,7 @@ agten_attach(device_t parent, device_t d
sc->sc_fb_is_open = 0;
sc->sc_video = -1;
sc->sc_bustag = sa->sa_bustag;
+ sc->sc_putchar = NULL;
sc->sc_width = prom_getpropint(node, "ffb_width", 1152);
sc->sc_height = prom_getpropint(node, "ffb_height", 900);
@@ -297,6 +308,15 @@ agten_attach(device_t parent, device_t d
ri = &sc->sc_console_screen.scr_ri;
+ sc->sc_gc.gc_bitblt = agten_bitblt;
+ sc->sc_gc.gc_rectfill = agten_rectfill;
+ sc->sc_gc.gc_blitcookie = sc;
+ sc->sc_gc.gc_rop = CR_COPY;
+
+#if defined(AGTEN_DEBUG)
+ sc->sc_height -= 200;
+#endif
+
if (console) {
vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
&defattr);
@@ -306,6 +326,14 @@ agten_attach(device_t parent, device_t d
sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
+ glyphcache_init(&sc->sc_gc,
+ sc->sc_height + 5,
+ (0x400000 / sc->sc_stride) - sc->sc_height - 5,
+ sc->sc_width,
+ ri->ri_font->fontwidth,
+ ri->ri_font->fontheight,
+ defattr);
+
wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
defattr);
i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, 0, 0,
@@ -317,6 +345,18 @@ agten_attach(device_t parent, device_t d
* since we're not the console we can postpone the rest
* until someone actually allocates a screen for us
*/
+ if (sc->sc_console_screen.scr_ri.ri_rows == 0) {
+ /* do some minimal setup to avoid weirdnesses later */
+ vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
+ &defattr);
+ }
+ glyphcache_init(&sc->sc_gc,
+ sc->sc_height + 5,
+ (0x400000 / sc->sc_stride) - sc->sc_height - 5,
+ sc->sc_width,
+ ri->ri_font->fontwidth,
+ ri->ri_font->fontheight,
+ defattr);
}
/* Initialize the default color map. */
@@ -470,12 +510,16 @@ agten_init_screen(void *cookie, struct v
}
rasops_init(ri, 0, 0);
+ sc->sc_putchar = ri->ri_ops.putchar;
+
ri->ri_caps = WSSCREEN_WSCOLORS;
rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
sc->sc_width / ri->ri_font->fontwidth);
ri->ri_hw = scr;
+ ri->ri_ops.putchar = agten_putchar;
+ ri->ri_ops.cursor = agten_cursor;
ri->ri_ops.copyrows = agten_copyrows;
ri->ri_ops.eraserows = agten_eraserows;
ri->ri_ops.copycols = agten_copycols;
@@ -688,6 +732,103 @@ agten_get_video(struct agten_softc *sc)
}
static void
+agten_bitblt(void *cookie, int xs, int ys, int xd, int yd, int wi, int he,
+ int rop)
+{
+ struct agten_softc *sc = cookie;
+
+ i128_bitblt(sc->sc_bustag, sc->sc_i128_regh,
+ xs, ys, xd, yd, wi, he, rop);
+}
+
+static void
+agten_rectfill(void *cookie, int x, int y, int wi, int he, long fg)
+{
+ struct agten_softc *sc = cookie;
+ struct vcons_screen *scr = sc->vd.active;
+ uint32_t col;
+
+ if (scr == NULL)
+ return;
+ col = scr->scr_ri.ri_devcmap[fg];
+ i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, x, y, wi, he, col);
+}
+
+static void
+agten_putchar(void *cookie, int row, int col, u_int c, long attr)
+{
+ struct rasops_info *ri = cookie;
+ struct wsdisplay_font *font = PICK_FONT(ri, c);
+ struct vcons_screen *scr = ri->ri_hw;
+ struct agten_softc *sc = scr->scr_cookie;
+ uint32_t fg, bg;
+ int x, y, wi, he, rv;
+
+ wi = font->fontwidth;
+ he = font->fontheight;
+
+ bg = ri->ri_devcmap[(attr >> 16) & 0xf];
+ fg = ri->ri_devcmap[(attr >> 24) & 0xf];
+
+ x = ri->ri_xorigin + col * wi;
+ y = ri->ri_yorigin + row * he;
+
+ if (c == 0x20) {
+ i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, x, y, wi, he,
+ bg);
+ if (attr & 1)
+ i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, x,
+ y + he - 2, wi, 1, fg);
+ return;
+ }
+ rv = glyphcache_try(&sc->sc_gc, c, x, y, attr);
+ if (rv == GC_OK)
+ return;
+ i128_sync(sc->sc_bustag, sc->sc_i128_regh);
+ sc->sc_putchar(cookie, row, col, c, attr & ~1);
+
+ if (rv == GC_ADD) {
+ glyphcache_add(&sc->sc_gc, c, x, y);
+ } else {
+ if (attr & 1)
+ i128_rectfill(sc->sc_bustag, sc->sc_i128_regh, x,
+ y + he - 2, wi, 1, fg);
+ }
+}
+
+static void
+agten_cursor(void *cookie, int on, int row, int col)
+{
+ struct rasops_info *ri = cookie;
+ struct vcons_screen *scr = ri->ri_hw;
+ struct agten_softc *sc = scr->scr_cookie;
+ int x, y, wi,he;
+
+ wi = ri->ri_font->fontwidth;
+ he = ri->ri_font->fontheight;
+
+ if (ri->ri_flg & RI_CURSOR) {
+ x = ri->ri_ccol * wi + ri->ri_xorigin;
+ y = ri->ri_crow * he + ri->ri_yorigin;
+ i128_bitblt(sc->sc_bustag, sc->sc_i128_regh, x, y, x, y, wi, he,
+ CR_COPY_INV);
+ ri->ri_flg &= ~RI_CURSOR;
+ }
+
+ ri->ri_crow = row;
+ ri->ri_ccol = col;
+
+ if (on)
+ {
+ x = ri->ri_ccol * wi + ri->ri_xorigin;
+ y = ri->ri_crow * he + ri->ri_yorigin;
+ i128_bitblt(sc->sc_bustag, sc->sc_i128_regh, x, y, x, y, wi, he,
+ CR_COPY_INV);
+ ri->ri_flg |= RI_CURSOR;
+ }
+}
+
+static void
agten_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
{
struct rasops_info *ri = cookie;
Index: src/sys/dev/sbus/files.sbus
diff -u src/sys/dev/sbus/files.sbus:1.38 src/sys/dev/sbus/files.sbus:1.39
--- src/sys/dev/sbus/files.sbus:1.38 Fri Sep 21 01:07:44 2012
+++ src/sys/dev/sbus/files.sbus Sat Oct 20 13:52:11 2012
@@ -1,4 +1,4 @@
-# $NetBSD: files.sbus,v 1.38 2012/09/21 01:07:44 macallan Exp $
+# $NetBSD: files.sbus,v 1.39 2012/10/20 13:52:11 macallan Exp $
#
# Config file and device description for machine-independent SBUS code.
# Included by ports that need it.
@@ -144,7 +144,7 @@ file dev/sbus/genfb_sbus.c genfb_sbus
# Fujitsu AG-10e
defflag opt_agten.h AGTEN_DEBUG
-device agten: fb, rasops8, bt_dac, wsemuldisplaydev, vcons
+device agten: fb, rasops8, bt_dac, wsemuldisplaydev, vcons, glyphcache
attach agten at sbus
file dev/sbus/agten.c agten needs-flag
file dev/ic/i128.c agten