Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/sbus - only sync the drawing engine when we're about...



details:   https://anonhg.NetBSD.org/src/rev/67161a84baac
branches:  trunk
changeset: 782204:67161a84baac
user:      macallan <macallan%NetBSD.org@localhost>
date:      Sat Oct 20 13:52:11 2012 +0000

description:
- 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

diffstat:

 sys/dev/sbus/agten.c    |  147 +++++++++++++++++++++++++++++++++++++++++++++++-
 sys/dev/sbus/files.sbus |    4 +-
 2 files changed, 146 insertions(+), 5 deletions(-)

diffs (255 lines):

diff -r 6e808739815a -r 67161a84baac sys/dev/sbus/agten.c
--- a/sys/dev/sbus/agten.c      Sat Oct 20 13:31:09 2012 +0000
+++ b/sys/dev/sbus/agten.c      Sat Oct 20 13:52:11 2012 +0000
@@ -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 @@
 #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 @@
 
        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_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 @@
        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 @@
 
        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 @@
                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 @@
                 * 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 @@
        }
 
        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 @@
 }
 
 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;
diff -r 6e808739815a -r 67161a84baac sys/dev/sbus/files.sbus
--- a/sys/dev/sbus/files.sbus   Sat Oct 20 13:31:09 2012 +0000
+++ b/sys/dev/sbus/files.sbus   Sat Oct 20 13:52:11 2012 +0000
@@ -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 @@
 
 # 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



Home | Main Index | Thread Index | Old Index