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